Skip to content

Commit

Permalink
perf: blazingly fast on the fly compilation
Browse files Browse the repository at this point in the history
  • Loading branch information
arthurfiorette committed Sep 11, 2023
1 parent 448856a commit 16789f5
Show file tree
Hide file tree
Showing 6 changed files with 99 additions and 76 deletions.
26 changes: 13 additions & 13 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -483,35 +483,35 @@ You can run this yourself by running `pnpm bench`. The bench below was with a Ap
```markdown
# Benchmark

- 2023-09-11T06:33:17.036Z
- 2023-09-11T18:08:10.527Z
- Node: v20.6.0
- V8: 10.2.154.26-node.26
- OS: darwin
- Arch: arm64
- V8: 11.3.244.8-node.14
- OS: linux
- Arch: x64

## Hello World

| Runs | @kitajs/html | typed-html | + | .compile() | + / @kitajs/html | + / typed-html |
| ------ | ------------ | ---------- | ----- | ---------- | ---------------- | -------------- |
| 10 | 0.0111ms | 0.0149ms | 1.34x | 0.0071ms | 1.56x | 2.1x |
| 10000 | 1.389ms | 4.3509ms | 3.13x | 0.5962ms | 2.33x | 7.3x |
| 100000 | 9.6386ms | 25.7452ms | 2.67x | 2.6383ms | 3.65x | 9.76x |
| 10 | 0.0105ms | 0.0154ms | 1.47x | 0.0067ms | 1.57x | 2.3x |
| 10000 | 0.9791ms | 3.285ms | 3.36x | 0.5294ms | 1.85x | 6.21x |
| 100000 | 10.3421ms | 34.3962ms | 3.33x | 3.539ms | 2.92x | 9.72x |

## Many Props

| Runs | @kitajs/html | typed-html | + | .compile() | + / @kitajs/html | + / typed-html |
| ------ | ------------ | ------------ | ----- | ---------- | ---------------- | -------------- |
| 10 | 0.8359ms | 2.4209ms | 2.9x | 0.0041ms | 203.88x | 590.46x |
| 10000 | 654.4648ms | 1696.169ms | 2.59x | 1.0713ms | 610.91x | 1583.28x |
| 100000 | 6022.4039ms | 13676.7311ms | 2.27x | 4.9011ms | 1228.79x | 2790.54x |
| 10 | 0.6015ms | 3.128ms | 5.2x | 0.0047ms | 127.98x | 665.53x |
| 10000 | 434.7339ms | 1408.6933ms | 3.24x | 0.94ms | 462.48x | 1498.61x |
| 100000 | 4323.8703ms | 13815.1441ms | 3.2x | 4.7838ms | 903.86x | 2887.9x |

## Big Component

| Runs | @kitajs/html | typed-html | + | .compile() | + / @kitajs/html | + / typed-html |
| ------ | ------------ | ----------- | ----- | ---------- | ---------------- | -------------- |
| 10 | 0.4776ms | 1.0979ms | 2.3x | 0.0052ms | 91.85x | 211.13x |
| 10000 | 411.6375ms | 987.0599ms | 2.4x | 1.2778ms | 322.15x | 772.47x |
| 100000 | 3986.7891ms | 9863.4924ms | 2.47x | 6.9333ms | 575.02x | 1422.63x |
| 10 | 0.3384ms | 1.0461ms | 3.09x | 0.0049ms | 69.06x | 213.49x |
| 10000 | 277.77ms | 1003.0324ms | 3.61x | 1.1829ms | 234.82x | 847.94x |
| 100000 | 2721.9826ms | 9898.4646ms | 3.64x | 5.6384ms | 482.76x | 1755.55x |
```
<br />
Expand Down
26 changes: 13 additions & 13 deletions benchmark.md
Original file line number Diff line number Diff line change
@@ -1,31 +1,31 @@
# Benchmark

- 2023-09-11T06:33:17.036Z
- 2023-09-11T18:08:10.527Z
- Node: v20.6.0
- V8: 10.2.154.26-node.26
- OS: darwin
- Arch: arm64
- V8: 11.3.244.8-node.14
- OS: linux
- Arch: x64

## Hello World

| Runs | @kitajs/html | typed-html | + | .compile() | + / @kitajs/html | + / typed-html |
| ------ | ------------ | ---------- | ----- | ---------- | ---------------- | -------------- |
| 10 | 0.0111ms | 0.0149ms | 1.34x | 0.0071ms | 1.56x | 2.1x |
| 10000 | 1.389ms | 4.3509ms | 3.13x | 0.5962ms | 2.33x | 7.3x |
| 100000 | 9.6386ms | 25.7452ms | 2.67x | 2.6383ms | 3.65x | 9.76x |
| 10 | 0.0105ms | 0.0154ms | 1.47x | 0.0067ms | 1.57x | 2.3x |
| 10000 | 0.9791ms | 3.285ms | 3.36x | 0.5294ms | 1.85x | 6.21x |
| 100000 | 10.3421ms | 34.3962ms | 3.33x | 3.539ms | 2.92x | 9.72x |

## Many Props

| Runs | @kitajs/html | typed-html | + | .compile() | + / @kitajs/html | + / typed-html |
| ------ | ------------ | ------------ | ----- | ---------- | ---------------- | -------------- |
| 10 | 0.8359ms | 2.4209ms | 2.9x | 0.0041ms | 203.88x | 590.46x |
| 10000 | 654.4648ms | 1696.169ms | 2.59x | 1.0713ms | 610.91x | 1583.28x |
| 100000 | 6022.4039ms | 13676.7311ms | 2.27x | 4.9011ms | 1228.79x | 2790.54x |
| 10 | 0.6015ms | 3.128ms | 5.2x | 0.0047ms | 127.98x | 665.53x |
| 10000 | 434.7339ms | 1408.6933ms | 3.24x | 0.94ms | 462.48x | 1498.61x |
| 100000 | 4323.8703ms | 13815.1441ms | 3.2x | 4.7838ms | 903.86x | 2887.9x |

## Big Component

| Runs | @kitajs/html | typed-html | + | .compile() | + / @kitajs/html | + / typed-html |
| ------ | ------------ | ----------- | ----- | ---------- | ---------------- | -------------- |
| 10 | 0.4776ms | 1.0979ms | 2.3x | 0.0052ms | 91.85x | 211.13x |
| 10000 | 411.6375ms | 987.0599ms | 2.4x | 1.2778ms | 322.15x | 772.47x |
| 100000 | 3986.7891ms | 9863.4924ms | 2.47x | 6.9333ms | 575.02x | 1422.63x |
| 10 | 0.3384ms | 1.0461ms | 3.09x | 0.0049ms | 69.06x | 213.49x |
| 10000 | 277.77ms | 1003.0324ms | 3.61x | 1.1829ms | 234.82x | 847.94x |
| 100000 | 2721.9826ms | 9898.4646ms | 3.64x | 5.6384ms | 482.76x | 1755.55x |
52 changes: 52 additions & 0 deletions benchmark/benny.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@

import Kita from '../index'
import { HelloWorld } from './hello-world'
import { BigComponent } from './big-component'
import { ManyProps } from './many-props'
// Avoids type-conflicts
const TypedHtml = require('typed-html')
const benny = require('benny')

export function suite(name: string, fn: Function) {
const compiled = Kita.compile<{ name: string }>((p) => fn(Kita, p.name))

function kita() {
return fn(Kita, name)
}

function compiledKita() {
return compiled({ name })
}

function typedHtml() {
return fn(TypedHtml, name)
}

// warms up the JIT
for (let i = 0; i < 100; i++) {
kita()
compiledKita()
typedHtml()
}

return benny.suite(
`Html generation (${name})`,

benny.add('@kitajs/html', kita),
benny.add('@kitajs/html - compiled', compiledKita),
benny.add('typed-html', typedHtml),

benny.configure({
cases: {
minSamples: 100
// minTime: 5
}
}),
benny.cycle(),
benny.complete()
)
}

suite('Hello World', HelloWorld)
suite('Many Props', ManyProps)
suite('Big Component', BigComponent)
9 changes: 5 additions & 4 deletions benchmark/index.tsx → benchmark/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,11 @@ import { BigComponent } from './big-component'
import { HelloWorld } from './hello-world'
import { ManyProps } from './many-props'
import { bench } from './suite'

function toMdRow(values: string[]) {
return '| ' + values.join(' | ') + ' |'
}

;(async () => {
const out = createWriteStream('benchmark.md', {
mode: 0o644,
Expand Down Expand Up @@ -47,7 +52,3 @@ import { bench } from './suite'
out.write('\n')
}
})().catch(console.error)

function toMdRow(values: string[]) {
return '| ' + values.join(' | ') + ' |'
}
46 changes: 0 additions & 46 deletions benchmark/suite.ts
Original file line number Diff line number Diff line change
@@ -1,53 +1,7 @@
// import benny from 'benny'
import Kita from '../index'
// Avoids type-conflicts
const TypedHtml = require('typed-html')

// export function suite(name: string, fn: Function) {
// const compiled = Kita.compile<['name']>((p) => fn(Kita, p.name))

// function kita() {
// return fn(Kita, name)
// }

// function compiledKita() {
// return compiled({ name })
// }

// function typedHtml() {
// return fn(TypedHtml, name)
// }

// // warms up the JIT
// for (let i = 0; i < 100; i++) {
// kita()
// compiledKita()
// typedHtml()
// }

// return benny.suite(
// `Html generation (${name})`,

// benny.add('@kitajs/html', kita),
// benny.add('@kitajs/html - compiled', compiledKita),
// benny.add('typed-html', typedHtml),

// benny.configure({
// cases: {
// minSamples: 100
// // minTime: 5
// }
// }),
// benny.cycle(),
// benny.complete()
// )
// }

// export function results(title: string, data: Record<string, number>[]) {
// console.log(`\n${title}\n`)
// console.table(data)
// }

export function bench(name: string, runs: number, fn: Function) {
const compiled = Kita.compile((p: { name: string }) => fn(Kita, p.name))

Expand Down
16 changes: 16 additions & 0 deletions index.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
/// <reference path="./jsx.d.ts" />

const ESCAPED_REGEX = /[\u00A0<>"'&]/;
const CAMEL_REGEX = /[a-z][A-Z]/;

/**
* A const used to represent a html fragment.
*
Expand Down Expand Up @@ -27,6 +30,12 @@ function isUpper (input, index) {
* @this {void}
*/
function toKebabCase (camel) {
// This is a optimization to avoid the whole conversion process when the
// string does not contain any uppercase characters.
if (!CAMEL_REGEX.test(camel)) {
return camel
}

const length = camel.length

let start = 0
Expand Down Expand Up @@ -56,6 +65,7 @@ function toKebabCase (camel) {
return kebab
}


/**
* Escapes a string for use in an HTML attribute value.
*
Expand All @@ -73,6 +83,12 @@ function escapeHtml (value) {

// Calls toString() on the value
value = String(value)
}

// This is a optimization to avoid the whole escaping process when the value
// does not contain any special characters.
if (!ESCAPED_REGEX.test(value)) {
return value;
}

const length = value.length
Expand Down

0 comments on commit 16789f5

Please sign in to comment.