creationix/http-parser-js

It's slower than native Node.js parser

szmarczak opened this issue · 1 comments

http-parser-js:

$ autocannon http://127.0.0.1:36273
Running 10s test @ http://127.0.0.1:36273
10 connections

┌─────────┬──────┬──────┬───────┬──────┬─────────┬─────────┬─────────┐
│ Stat    │ 2.5% │ 50%  │ 97.5% │ 99%  │ Avg     │ Stdev   │ Max     │
├─────────┼──────┼──────┼───────┼──────┼─────────┼─────────┼─────────┤
│ Latency │ 0 ms │ 0 ms │ 0 ms  │ 0 ms │ 0.01 ms │ 0.05 ms │ 5.23 ms │
└─────────┴──────┴──────┴───────┴──────┴─────────┴─────────┴─────────┘
┌───────────┬────────┬────────┬─────────┬─────────┬──────────┬─────────┬────────┐
│ Stat      │ 1%     │ 2.5%   │ 50%     │ 97.5%   │ Avg      │ Stdev   │ Min    │
├───────────┼────────┼────────┼─────────┼─────────┼──────────┼─────────┼────────┤
│ Req/Sec   │ 30975  │ 30975  │ 39167   │ 39359   │ 38166.55 │ 2387.68 │ 30973  │
├───────────┼────────┼────────┼─────────┼─────────┼──────────┼─────────┼────────┤
│ Bytes/Sec │ 3.5 MB │ 3.5 MB │ 4.42 MB │ 4.45 MB │ 4.31 MB  │ 270 kB  │ 3.5 MB │
└───────────┴────────┴────────┴─────────┴─────────┴──────────┴─────────┴────────┘

Req/Bytes counts sampled once per second.

420k requests in 11.04s, 47.4 MB read

Native Node.js:

$ autocannon -c 10 http://127.0.0.1:41365
Running 10s test @ http://127.0.0.1:41365
10 connections

┌─────────┬──────┬──────┬───────┬──────┬─────────┬─────────┬─────────┐
│ Stat    │ 2.5% │ 50%  │ 97.5% │ 99%  │ Avg     │ Stdev   │ Max     │
├─────────┼──────┼──────┼───────┼──────┼─────────┼─────────┼─────────┤
│ Latency │ 0 ms │ 0 ms │ 0 ms  │ 0 ms │ 0.01 ms │ 0.03 ms │ 4.88 ms │
└─────────┴──────┴──────┴───────┴──────┴─────────┴─────────┴─────────┘
┌───────────┬─────────┬─────────┬─────────┬─────────┬─────────┬─────────┬─────────┐
│ Stat      │ 1%      │ 2.5%    │ 50%     │ 97.5%   │ Avg     │ Stdev   │ Min     │
├───────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┤
│ Req/Sec   │ 49983   │ 49983   │ 55551   │ 56127   │ 54861.1 │ 1672.23 │ 49958   │
├───────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┤
│ Bytes/Sec │ 5.65 MB │ 5.65 MB │ 6.28 MB │ 6.34 MB │ 6.2 MB  │ 189 kB  │ 5.65 MB │
└───────────┴─────────┴─────────┴─────────┴─────────┴─────────┴─────────┴─────────┘

Req/Bytes counts sampled once per second.

603k requests in 11.04s, 68.2 MB read

Code:

process.binding('http_parser').HTTPParser = require('http-parser-js').HTTPParser;

const http = require('http');

const server = http.createServer((req, res) => {
    res.end('Hello, world!');
}).listen(() => {
    console.log(`http://127.0.0.1:${server.address().port}`);
});

It's 1.44x slower than the native Node.js implementation. Tested on i7-7700k.

That's good to hear! The Node native parser has been rewritten a couple times in the past 4 years, so should be faster at this point. Though, parsing a single, small HTTP request that arrives as a single packet is definitely where the a native parser will be most efficient anyway. As stated in the README, the primary purpose of this module now is for durability of the parser (handling non-conformant HTTP requests/responses), not performance.