-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Benchmark for React Native (Hermes) target (#47)
Size of the bytecode outputs: - `graphemer`: 140 KB - `unicode-segmenter/grapheme`: 48 KB Perf benchmark result on a MacBook Pro M1 laptop: ``` graphemer (small input) samples: 1000 duration (avg): 0.326 graphemer (medium input) samples: 1000 duration (avg): 1.611 unicode-segmenter/grapheme (small input) samples: 1000 duration (avg): 0.14 unicode-segmenter/grapheme (medium input) samples: 1000 medium input (avg): 0.674 ```
- Loading branch information
Showing
7 changed files
with
2,818 additions
and
47 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -22,3 +22,6 @@ lcov.info | |
|
||
/.parcel-cache/ | ||
/dist/ | ||
|
||
*.hermes.js | ||
*.hermes.hbc |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
import Graphemer from 'graphemer'; | ||
|
||
import { inputs, simpleBench } from '../suite.js'; | ||
|
||
let graphemer = new (Graphemer.default || Graphemer)(); | ||
|
||
{ | ||
let result = simpleBench(1000, () => { | ||
void [...graphemer.iterateGraphemes(inputs.small)]; | ||
}); | ||
|
||
print(`graphemer (small input)`); | ||
print(`samples: ${result.samples}`); | ||
print(`duration (avg): ${result.avgDuration}`); | ||
} | ||
|
||
|
||
{ | ||
let result = simpleBench(1000, () => { | ||
void [...graphemer.iterateGraphemes(inputs.medium)]; | ||
}); | ||
|
||
print(); | ||
print(`graphemer (medium input)`); | ||
print(`samples: ${result.samples}`); | ||
print(`duration (avg): ${result.avgDuration}`); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
import * as path from 'node:path'; | ||
import * as fs from 'node:fs/promises'; | ||
import Metro from 'metro'; | ||
import { $ } from 'zx'; | ||
|
||
let baseDir = import.meta.dirname; | ||
|
||
$.cwd = baseDir; | ||
|
||
let config = await Metro.loadConfig(undefined, { | ||
transformer: { | ||
enableBabelRCLookup: false, | ||
babelTransformerPath: '@react-native/metro-babel-transformer', | ||
}, | ||
reporter: { | ||
update: () => {}, | ||
}, | ||
}); | ||
|
||
let libs = [ | ||
'graphemer', | ||
'unicode-segmenter', | ||
]; | ||
|
||
let benches = []; | ||
|
||
console.group('Preparing bundles...'); | ||
|
||
for (let lib of libs) { | ||
let libDir = path.join(baseDir, lib); | ||
|
||
let files = await fs.readdir(libDir); | ||
files = files.filter(file => file.endsWith('.js') && !file.includes('hermes')); | ||
|
||
for (let file of files) { | ||
let source = path.join(libDir, file); | ||
let hermesEntry = path.join(libDir, file.replace(/\.js$/, '.hermes.js')); | ||
let hermesBin = path.join(libDir, file.replace(/\.js$/, '.hermes.hbc')); | ||
|
||
await Metro.runBuild(config, { | ||
entry: path.join(libDir, file), | ||
out: hermesEntry, | ||
dev: false, | ||
}); | ||
|
||
console.log(`Compiling bundle to ${hermesBin}`); | ||
await $`hermes -emit-binary -out ${hermesBin} ${hermesEntry}`; | ||
|
||
console.log(); | ||
|
||
benches.push({ | ||
lib, | ||
source, | ||
hermesBin, | ||
hermesEntry, | ||
}); | ||
} | ||
} | ||
|
||
console.groupEnd(); | ||
|
||
console.log('\nExecuting Hermes bytecodes...\n'); | ||
|
||
for (let bench of benches) { | ||
await $({ stdio: 'inherit' })`hermes ${bench.hermesBin}`; | ||
console.log(); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
export let inputs = { | ||
small: `🚀 새로운 유니코드 분할기 라이브러리 \'unicode-segmenter\'를 소개합니다! 🔍 각종 언어의 문자를 정확하게 구분해주는 강력한 도구입니다. Check it out! 👉 [https://github.com/cometkim/unicode-segmenter] #Unicode #Programming 🌐`, | ||
|
||
medium: `The quick brown 🦊 fox jumps over 13 lazy 🐶 dogs. हिंदी भाषा में स्वागत है. 中文环境的介绍。日本語での説明。АБВГД ЕЁЖЗ ИЙКЛМН ОПРСТ УФХЦЧ ШЩЪЫЬ ЭЮЯ. السَّلَامُ عَلَيْكُمْ. 1234567890!@# $%^&*()_+[];'./,\<>?:"{}|= abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ 🌍 🚀 ✨. 𐍈𐍉𐌽𐌴𐍄𐌹𐌲𐍉𐌸𐌰𐍃𐌰𐍂𐌺𐍃 𐌲𐌴𐍂𐌰𐌼𐌰𐌽𐌹𐍃𐌺𐌰𐌹𐍃𐌰𐍂𐌰𐌶𐌳𐌰. 🧙♂️⚔️🏰👸🐉🏹🛡️🌌. ¡Hola! ¿Cómo estás? 🎉🎊🎈. Dans un village de La Mancha, dont je ne veux pas me souvenir du nom, vivait pas si longtemps, un hidalgo des lances reposées, ancien bouclier, cheval maigre et lévrier rapide. O Romeo, Romeo! wherefore art thou Romeo? Deny thy father and refuse thy name; Or, if thou wilt not, be but sworn my love, And I'll no longer be a Capulet. 세계의 모든 인간은 자유롭고 평등하게 태어났다. 人人生而自由,在尊严和权利上一律平等。Είναι ελεύθεροι και ίσοι στην αξιοπρέπεια και τα δικαιώματα. כָּל אָדָם נוֹלָד חוֹפְשִׁי וּשְׁוֵה בַּכָּבוֹד וּבַזְּכוּיוֹת.`, | ||
}; | ||
|
||
/** | ||
* @param {number} nums | ||
* @param {() => void} callback | ||
*/ | ||
export function simpleBench(nums, callback) { | ||
// warmup | ||
for (let i = 0; i < 100; i++) { | ||
void callback(); | ||
} | ||
|
||
let startAt = Date.now(); | ||
for (let i = 0; i < nums; i++) { | ||
void callback(); | ||
} | ||
let endAt = Date.now(); | ||
let totalDuration = endAt - startAt; | ||
let avgDuration = totalDuration / nums; | ||
|
||
return { | ||
samples: nums, | ||
startAt, | ||
endAt, | ||
totalDuration, | ||
avgDuration, | ||
}; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
import { graphemeSegments } from '../../../src/grapheme.js'; | ||
|
||
import { inputs, simpleBench } from '../suite.js'; | ||
|
||
{ | ||
let result = simpleBench(1000, () => { | ||
void [...graphemeSegments(inputs.small)]; | ||
}); | ||
|
||
print(`unicode-segmenter/grapheme (small input)`); | ||
print(`samples: ${result.samples}`); | ||
print(`duration (avg): ${result.avgDuration}`); | ||
} | ||
|
||
{ | ||
let result = simpleBench(1000, () => { | ||
void [...graphemeSegments(inputs.medium)]; | ||
}); | ||
|
||
print(); | ||
print(`unicode-segmenter/grapheme (medium input)`); | ||
print(`samples: ${result.samples}`); | ||
print(`medium input (avg): ${result.avgDuration}`); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -102,7 +102,8 @@ | |
"perf:emoji": "node benchmark/performance-emoji.js", | ||
"perf:general": "node benchmark/performance-general.js", | ||
"perf:grapheme": "node benchmark/performance-grapheme.js", | ||
"perf:grapheme:browser": "vite benchmark/performance-grapheme" | ||
"perf:grapheme:browser": "vite benchmark/performance-grapheme", | ||
"perf:hermes": "node benchmark/hermes/run.js" | ||
}, | ||
"alias": { | ||
"process": false | ||
|
@@ -111,6 +112,7 @@ | |
"@changesets/cli": "^2.27.1", | ||
"@formatjs/intl-segmenter": "11.5.7", | ||
"@jazzer.js/core": "^2.1.0", | ||
"@react-native/metro-babel-transformer": "^0.74.84", | ||
"@types/node": "^20.12.7", | ||
"@types/xregexp": "^4.4.0", | ||
"emoji-regex": "10.3.0", | ||
|
@@ -119,6 +121,7 @@ | |
"fast-check": "^3.17.1", | ||
"grapheme-splitter": "1.0.4", | ||
"graphemer": "1.4.0", | ||
"metro": "^0.80.9", | ||
"mitata": "^0.1.11", | ||
"os-browserify": "^0.3.0", | ||
"pretty-bytes": "^6.1.1", | ||
|
@@ -127,7 +130,8 @@ | |
"typescript": "^5.4.5", | ||
"unicode-segmentation-wasm": "portal:benchmark/unicode-segmentation-wasm", | ||
"vite": "^5.2.11", | ||
"xregexp": "5.1.1" | ||
"xregexp": "5.1.1", | ||
"zx": "^8.1.3" | ||
}, | ||
"packageManager": "[email protected]" | ||
} |
Oops, something went wrong.