Skip to content

Commit 42753bf

Browse files
authored
chore: Added WASM benchmarks. (#815)
* chore: Added WASM benchmarks. Signed-off-by: Paolo Insogna <paolo@cowtech.it> * fixup Signed-off-by: Paolo Insogna <paolo@cowtech.it> --------- Signed-off-by: Paolo Insogna <paolo@cowtech.it>
1 parent 19e5f4e commit 42753bf

File tree

5 files changed

+133
-1
lines changed

5 files changed

+133
-1
lines changed

Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ all: build/libllhttp.a build/libllhttp.so
2020
clean:
2121
rm -rf release/
2222
rm -rf build/
23+
rm -rf test/tmp
2324

2425
build/libllhttp.so: build/c/llhttp.o build/native/api.o \
2526
build/native/http.o
File renamed without changes.

bench/wasm.ts

Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
1+
import { readFile } from "fs/promises";
2+
import * as constants from "../build/wasm/constants.js";
3+
4+
function http(input) {
5+
return input
6+
.trim()
7+
.replaceAll(/^\s+/gm, "")
8+
.replaceAll("\n", "")
9+
.replaceAll("\\r", "\r")
10+
.replaceAll("\\n", "\n");
11+
}
12+
13+
function formatNumber(num, precision) {
14+
return num
15+
.toLocaleString("en-US", {
16+
minimumFractionDigits: precision,
17+
maximumFractionDigits: precision,
18+
useGrouping: "always",
19+
})
20+
.replaceAll(",", "_");
21+
}
22+
23+
/* eslint-disable @stylistic/max-len */
24+
const samples = {
25+
seanmonstar_httparse: http(`
26+
GET /wp-content/uploads/2010/03/hello-kitty-darth-vader-pink.jpg HTTP/1.1\\r\\n
27+
Host: www.kittyhell.com\\r\\n
28+
User-Agent: Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.6; ja-JP-mac; rv:1.9.2.3) Gecko/20100401 Firefox/3.6.3 Pathtraq/0.9\\r\\n
29+
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\\r\\n
30+
Accept-Language: ja,en-us;q=0.7,en;q=0.3\\r\\n
31+
Accept-Encoding: gzip,deflate\\r\\n
32+
Accept-Charset: Shift_JIS,utf-8;q=0.7,*;q=0.7\\r\\n
33+
Keep-Alive: 115\\r\\n
34+
Connection: keep-alive\\r\\n
35+
Cookie: wp_ozh_wsa_visits=2; wp_ozh_wsa_visit_lasttime=xxxxxxxxxx; __utma=xxxxxxxxx.xxxxxxxxxx.xxxxxxxxxx.xxxxxxxxxx.xxxxxxxxxx.x; __utmz=xxxxxxxxx.xxxxxxxxxx.x.x.utmccn=(referral)|utmcsr=reader.livedoor.com|utmcct=/reader/|utmcmd=referral\\r\\n\\r\\n
36+
`),
37+
nodejs_http_parser: http(`
38+
POST /joyent/http-parser HTTP/1.1\\r\\n
39+
Host: github.com\\r\\n
40+
DNT: 1\\r\\n
41+
Accept-Encoding: gzip, deflate, sdch\\r\\n
42+
Accept-Language: ru-RU,ru;q=0.8,en-US;q=0.6,en;q=0.4\\r\\n
43+
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_1)
44+
AppleWebKit/537.36 (KHTML, like Gecko)
45+
Chrome/39.0.2171.65 Safari/537.36\\r\\n
46+
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,
47+
image/webp,*/*;q=0.8\\r\\n
48+
Referer: https://github.com/joyent/http-parser\\r\\n
49+
Connection: keep-alive\\r\\n
50+
Transfer-Encoding: chunked\\r\\n
51+
Cache-Control: max-age=0\\r\\n\\r\\nb\\r\\nhello world\\r\\n0\\r\\n\\r\\n
52+
`)
53+
};
54+
/* eslint-enable @stylistic/max-len */
55+
56+
async function main () {
57+
const mod = await WebAssembly.compile(
58+
await readFile(new URL("../build/wasm/llhttp.wasm", import.meta.url))
59+
);
60+
61+
const { exports: llhttp } = await WebAssembly.instantiate(mod, {
62+
env: {
63+
wasm_on_url() {
64+
return 0;
65+
},
66+
wasm_on_status() {
67+
return 0;
68+
},
69+
wasm_on_message_begin() {
70+
return 0;
71+
},
72+
wasm_on_header_field() {
73+
return 0;
74+
},
75+
wasm_on_header_value() {
76+
return 0;
77+
},
78+
wasm_on_headers_complete() {
79+
return 0;
80+
},
81+
wasm_on_body() {
82+
return 0;
83+
},
84+
wasm_on_message_complete() {
85+
return 0;
86+
},
87+
},
88+
});
89+
90+
for (const [ name, payload ] of Object.entries(samples)) {
91+
const len = payload.length;
92+
const iterations = 2 ** 33 / len;
93+
const total = iterations * len;
94+
95+
const parser = llhttp.llhttp_alloc(constants.TYPE.BOTH);
96+
const ptr = llhttp.malloc(len);
97+
new Uint8Array(llhttp.memory.buffer, ptr, len).set(Buffer.from(payload));
98+
99+
const start = process.hrtime.bigint();
100+
for (let i = 0; i < iterations; i++) {
101+
llhttp.llhttp_execute(parser, ptr, len);
102+
}
103+
104+
llhttp.free(ptr);
105+
llhttp.llhttp_free(ptr);
106+
107+
const time = Number(process.hrtime.bigint() - start) / 1e9;
108+
const bw = total / time;
109+
110+
const label = name.padStart(21, " ");
111+
const samples = formatNumber(iterations, 0).padStart(12);
112+
const size = formatNumber(total / (1024 * 1024), 2).padStart(8);
113+
const speed = formatNumber(bw / (1024 * 1024), 2).padStart(10);
114+
const throughtput = formatNumber(iterations / time, 2).padStart(10);
115+
const duration = formatNumber(time, 2).padStart(6);
116+
117+
console.log(
118+
`${label} | ${samples} samples | ${size} MB | ${speed} MB/s | ${throughtput} ops/sec | ${duration} s`
119+
);
120+
}
121+
}
122+
123+
main()

bin/build_wasm.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,8 +40,14 @@ if (process.argv[2] === '--docker') {
4040
if (process.platform === 'linux') {
4141
cmd += ` --user ${process.getuid!()}:${process.getegid!()}`;
4242
}
43+
44+
if(process.env.NO_SSE) {
45+
cmd += ` -e NO_SSE=${process.env.NO_SSE}`
46+
}
47+
4348
cmd += ` --mount type=bind,source=${WASM_SRC}/build,target=/home/node/llhttp/build llhttp_wasm_builder npm run wasm`;
4449

50+
4551
console.log(`> ${cmd}\n\n`);
4652
execSync(cmd, { cwd: WASM_SRC, stdio: 'inherit' });
4753
process.exit(0);
@@ -67,6 +73,7 @@ execSync(
6773
-fno-exceptions \
6874
-fvisibility=hidden \
6975
-mexec-model=reactor \
76+
${process.env.NO_SSE ? '' : '-msimd128'} \
7077
-Wl,-error-limit=0 \
7178
-Wl,-O3 \
7279
-Wl,--lto-O3 \

package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,8 @@
99
"src"
1010
],
1111
"scripts": {
12-
"bench": "node --import tsx bench/index.ts",
12+
"bench": "node --import tsx bench/native.ts",
13+
"bench-wasm": "node --import tsx bench/wasm.ts",
1314
"build": "node --import tsx bin/generate.ts",
1415
"build-ts": "tsc",
1516
"prebuild-wasm": "npm run wasm -- --prebuild && npm run wasm -- --setup",

0 commit comments

Comments
 (0)