Skip to content

Commit

Permalink
feat: support JIT like compilation (#1434)
Browse files Browse the repository at this point in the history
  • Loading branch information
kazupon authored Jun 27, 2023
1 parent 69e033b commit a28060b
Show file tree
Hide file tree
Showing 83 changed files with 6,124 additions and 1,257 deletions.
2 changes: 2 additions & 0 deletions .textlintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ module.exports = {
'max-doc-width': 360,
'unexpanded-acronym': {
ignore_acronyms: [
'JIT',
'AOT',
'UMD',
'NPM',
'CDN',
Expand Down
82 changes: 82 additions & 0 deletions benchmark/complex-jit-aot.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
import { createCommonJS } from 'mlly'
import { baseCompile } from '@intlify/message-compiler'
import {
translate,
createCoreContext,
compile,
registerMessageCompiler,
clearCompileCache
} from '@intlify/core-base'
import { createI18n } from 'vue-i18n'
import { resolve, dirname } from 'pathe'
import { readJson } from './utils.mjs'

const { require } = createCommonJS(import.meta.url)
const { Suite } = require('benchmark')

function precompile(data) {
const keys = Object.keys(data)
keys.forEach(key => {
const { ast } = baseCompile(data[key], { jit: true, location: false })
data[key] = ast
})
return data
}

async function main() {
const resources = await readJson(
resolve(dirname('.'), './benchmark/complex.json')
)
const len = Object.keys(resources).length

console.log(`complex pattern on ${len} resources (JIT + AOT):`)
console.log()

registerMessageCompiler(compile)
const precompiledResources = precompile(resources)

const ctx = createCoreContext({
locale: 'en',
modifiers: {
caml: val => val
},
messages: {
en: precompiledResources
}
})

const i18n = createI18n({
legacy: false,
locale: 'en',
modifiers: {
caml: val => val
},
messages: {
en: precompiledResources
}
})

new Suite('complex pattern')
.add(`resolve time with core`, () => {
translate(ctx, 'complex500', 2)
})
.add(`resolve time on composition`, () => {
clearCompileCache()
i18n.global.t('complex500', 2)
})
.add(`resolve time on composition with compile cache`, () => {
i18n.global.t('complex500', 2)
})
.on('error', event => {
console.log(String(event.target))
})
.on('cycle', event => {
console.log(String(event.target))
})
.run()
}

main().catch(err => {
console.error(err)
process.exit(1)
})
71 changes: 71 additions & 0 deletions benchmark/complex-jit.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
import { createCommonJS } from 'mlly'
import {
translate,
createCoreContext,
compile,
registerMessageCompiler,
clearCompileCache
} from '@intlify/core-base'
import { createI18n } from 'vue-i18n'
import { resolve, dirname } from 'pathe'
import { readJson } from './utils.mjs'

const { require } = createCommonJS(import.meta.url)
const { Suite } = require('benchmark')

async function main() {
const resources = await readJson(
resolve(dirname('.'), './benchmark/complex.json')
)
const len = Object.keys(resources).length

console.log(`complex pattern on ${len} resources (JIT):`)
console.log()

registerMessageCompiler(compile)

const ctx = createCoreContext({
locale: 'en',
modifiers: {
caml: val => val
},
messages: {
en: resources
}
})

const i18n = createI18n({
legacy: false,
locale: 'en',
modifiers: {
caml: val => val
},
messages: {
en: resources
}
})

new Suite('complex pattern')
.add(`resolve time with core`, () => {
translate(ctx, 'complex500', 2)
})
.add(`resolve time on composition`, () => {
clearCompileCache()
i18n.global.t('complex500', 2)
})
.add(`resolve time on composition with compile cache`, () => {
i18n.global.t('complex500', 2)
})
.on('error', event => {
console.log(String(event.target))
})
.on('cycle', event => {
console.log(String(event.target))
})
.run()
}

main().catch(err => {
console.error(err)
process.exit(1)
})
62 changes: 28 additions & 34 deletions benchmark/complex.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -12,51 +12,45 @@ const { require } = createCommonJS(import.meta.url)
const { Suite } = require('benchmark')

async function main() {
const data = await readJson(resolve(dirname('.'), './benchmark/complex.json'))
const len = Object.keys(data).length
const resources = await readJson(
resolve(dirname('.'), './benchmark/complex.json')
)
const len = Object.keys(resources).length

console.log(`complex pattern on ${len} resources:`)
console.log(`complex pattern on ${len} resources (AOT):`)
console.log()

let i18n
const ctx = createCoreContext({
locale: 'en',
modifiers: {
caml: val => val
},
messages: {
en: resources
}
})

const i18n = createI18n({
legacy: false,
locale: 'en',
modifiers: {
caml: val => val
},
messages: {
en: resources
}
})

new Suite('complex pattern')
.add(`resolve time with core`, () => {
const ctx = createCoreContext({
locale: 'en',
modifiers: {
caml: val => val
},
messages: {
en: data
}
})
for (const [key] of Object.entries(data)) {
translate(ctx, key, 2)
}
translate(ctx, 'complex500', 2)
})
.add(`resolve time on composition`, () => {
clearCompileCache()

i18n = createI18n({
legacy: false,
locale: 'en',
modifiers: {
caml: val => val
},
messages: {
en: data
}
})

for (const [key] of Object.entries(data)) {
i18n.global.t(key, 2)
}
i18n.global.t('complex500', 2)
})
.add(`resolve time on composition with compile cache`, () => {
for (const [key] of Object.entries(data)) {
i18n.global.t(key, 2)
}
i18n.global.t('complex500', 2)
})
.on('error', event => {
console.log(String(event.target))
Expand Down
36 changes: 24 additions & 12 deletions benchmark/index.mjs
Original file line number Diff line number Diff line change
@@ -1,26 +1,38 @@
import { exec } from 'child_process'
import { dirname } from 'pathe'
import { spawn } from 'child_process'

function run(pattner) {
return new Promise((resolve, reject) => {
exec(
`node ./benchmark/${pattner}.mjs`,
{ cwd: dirname('.') },
(error, stdout) => {
if (error) {
return reject(error)
}
console.log(stdout)
const child = spawn('node', [`./benchmark/${pattner}.mjs`], {
stdio: 'inherit'
})

child.once('error', err => {
reject(err)
})

child.once('exit', code => {
if (code !== 0) {
reject(new Error(`exit with code ${code}`))
} else {
resolve()
}
)
})
})
}

;(async () => {
try {
for (const p of ['compile', 'simple', 'complex']) {
for (const p of [
'compile',
'simple',
'simple-jit',
'simple-jit-aot',
'complex',
'complex-jit',
'complex-jit-aot'
]) {
await run(p)
console.log()
}
} catch (e) {
console.error(e)
Expand Down
75 changes: 75 additions & 0 deletions benchmark/simple-jit-aot.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
import { createCommonJS } from 'mlly'
import { baseCompile } from '@intlify/message-compiler'
import {
translate,
createCoreContext,
compile,
registerMessageCompiler,
clearCompileCache
} from '@intlify/core-base'
import { createI18n } from 'vue-i18n'
import { resolve, dirname } from 'pathe'
import { readJson } from './utils.mjs'

const { require } = createCommonJS(import.meta.url)
const { Suite } = require('benchmark')

function precompile(data) {
const keys = Object.keys(data)
keys.forEach(key => {
const { ast } = baseCompile(data[key], { jit: true, location: false })
data[key] = ast
})
return data
}

async function main() {
const resources = await readJson(
resolve(dirname('.'), './benchmark/simple.json')
)
const len = Object.keys(resources).length

console.log(`simple pattern on ${len} resources (JIT + AOT):`)
console.log()

registerMessageCompiler(compile)
const precompiledResources = precompile(resources)

const ctx = createCoreContext({
locale: 'en',
messages: {
en: precompiledResources
}
})
const i18n = createI18n({
legacy: false,
locale: 'en',
messages: {
en: precompiledResources
}
})

new Suite('simple pattern')
.add(`resolve time with core`, () => {
translate(ctx, 'hello500')
})
.add(`resolve time on composition`, () => {
clearCompileCache()
i18n.global.t('hello500')
})
.add(`resolve time on composition with compile cache`, () => {
i18n.global.t('hello500')
})
.on('error', event => {
console.log(String(event.target))
})
.on('cycle', event => {
console.log(String(event.target))
})
.run()
}

main().catch(err => {
console.error(err)
process.exit(1)
})
Loading

0 comments on commit a28060b

Please sign in to comment.