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+ const samples = {
24+ seanmonstar_httparse : http ( `
25+ GET /wp-content/uploads/2010/03/hello-kitty-darth-vader-pink.jpg HTTP/1.1\\r\\n
26+ Host: www.kittyhell.com\\r\\n
27+ 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
28+ Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\\r\\n
29+ Accept-Language: ja,en-us;q=0.7,en;q=0.3\\r\\n
30+ Accept-Encoding: gzip,deflate\\r\\n
31+ Accept-Charset: Shift_JIS,utf-8;q=0.7,*;q=0.7\\r\\n
32+ Keep-Alive: 115\\r\\n
33+ Connection: keep-alive\\r\\n
34+ 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
35+ ` ) ,
36+ nodejs_http_parser : http ( `
37+ POST /joyent/http-parser HTTP/1.1\\r\\n
38+ Host: github.com\\r\\n
39+ DNT: 1\\r\\n
40+ Accept-Encoding: gzip, deflate, sdch\\r\\n
41+ Accept-Language: ru-RU,ru;q=0.8,en-US;q=0.6,en;q=0.4\\r\\n
42+ User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_1)
43+ AppleWebKit/537.36 (KHTML, like Gecko)
44+ Chrome/39.0.2171.65 Safari/537.36\\r\\n
45+ Accept: text/html,application/xhtml+xml,application/xml;q=0.9,
46+ image/webp,*/*;q=0.8\\r\\n
47+ Referer: https://github.com/joyent/http-parser\\r\\n
48+ Connection: keep-alive\\r\\n
49+ Transfer-Encoding: chunked\\r\\n
50+ Cache-Control: max-age=0\\r\\n\\r\\nb\\r\\nhello world\\r\\n0\\r\\n\\r\\n
51+ ` )
52+ } ;
53+
54+ async function main ( ) {
55+ const mod = await WebAssembly . compile (
56+ await readFile ( new URL ( "../build/wasm/llhttp.wasm" , import . meta. url ) )
57+ ) ;
58+
59+ const { exports : llhttp } = await WebAssembly . instantiate ( mod , {
60+ env : {
61+ wasm_on_url ( ) {
62+ return 0 ;
63+ } ,
64+ wasm_on_status ( ) {
65+ return 0 ;
66+ } ,
67+ wasm_on_message_begin ( ) {
68+ return 0 ;
69+ } ,
70+ wasm_on_header_field ( ) {
71+ return 0 ;
72+ } ,
73+ wasm_on_header_value ( ) {
74+ return 0 ;
75+ } ,
76+ wasm_on_headers_complete ( ) {
77+ return 0 ;
78+ } ,
79+ wasm_on_body ( ) {
80+ return 0 ;
81+ } ,
82+ wasm_on_message_complete ( ) {
83+ return 0 ;
84+ } ,
85+ } ,
86+ } ) ;
87+
88+ for ( const [ name , payload ] of Object . entries ( samples ) ) {
89+ const len = payload . length ;
90+ const iterations = 2 ** 33 / len ;
91+ const total = iterations * len ;
92+
93+ const parser = llhttp . llhttp_alloc ( constants . TYPE . BOTH ) ;
94+ const ptr = llhttp . malloc ( len ) ;
95+ new Uint8Array ( llhttp . memory . buffer , ptr , len ) . set ( Buffer . from ( payload ) ) ;
96+
97+ let start = process . hrtime . bigint ( ) ;
98+ for ( let i = 0 ; i < iterations ; i ++ ) {
99+ const ret = llhttp . llhttp_execute ( parser , ptr , len ) ;
100+ }
101+
102+ llhttp . free ( ptr ) ;
103+ llhttp . llhttp_free ( ptr ) ;
104+
105+ const time = Number ( process . hrtime . bigint ( ) - start ) / 1e9 ;
106+ const bw = total / time ;
107+
108+ const label = name . padStart ( 21 , " " ) ;
109+ const samples = formatNumber ( iterations , 0 ) . padStart ( 12 ) ;
110+ const size = formatNumber ( total / ( 1024 * 1024 ) , 2 ) . padStart ( 8 ) ;
111+ const speed = formatNumber ( bw / ( 1024 * 1024 ) , 2 ) . padStart ( 10 ) ;
112+ const throughtput = formatNumber ( iterations / time , 2 ) . padStart ( 10 ) ;
113+ const duration = formatNumber ( time , 2 ) . padStart ( 6 ) ;
114+
115+ console . log (
116+ `${ label } | ${ samples } samples | ${ size } MB | ${ speed } MB/s | ${ throughtput } ops/sec | ${ duration } s`
117+ ) ;
118+ }
119+ }
120+
121+ main ( )
0 commit comments