http: add native single-shot response builder#64393
Conversation
|
Review requested:
|
Serialize the common HTTP/1.1 header block (and optional body) in C++ so _storeHeader and ServerResponse.end avoid repeated JS string concatenation and multi-write path overhead. The public API and wire format are unchanged; complex cases fall back to the existing JS path. On benchmark/http/simple.js (bytes/4/1, 50 connections, 5s) this raised throughput from ~80k to ~118-126k req/s (~+48% to +58%) on the same machine. Signed-off-by: Yagiz Nizipli <yagiz@nizipli.com>
6e25748 to
8a0057a
Compare
Revert incidental ConnectionsList reformatting in node_http_parser.cc, document the buildHttpMessage flag and out-param slots in JS, and avoid Buffer.concat when pairing headers with a body by queueing a separate latin1 header write instead. Signed-off-by: Yagiz Nizipli <yagiz@nizipli.com>
Hot writeHead()+end() now flushes via tryFastFlushEnd instead of the full write_()/extra empty write path. Server-side native headers stay as Buffers (no latin1 string copy) until write time; the C++ builder writes into a single malloc transferred to Buffer (no std::string + Copy). Reuse a scratch flat-header array and a prebuilt 200 status line. Signed-off-by: Yagiz Nizipli <yagiz@nizipli.com>
mcollina
left a comment
There was a problem hiding this comment.
lgtm
This needs a CITGM run and some validation it doesn't break express, fastify, koa, etc before shipping.
|
The
notable-change
Please suggest a text for the release notes if you'd like to include a more detailed summary, then proceed to update the PR description with the text or a link to the notable change suggested text comment. Otherwise, the commit will be placed in the Other Notable Changes section. |
|
Also a benchmark CI run would be interesting. |
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #64393 +/- ##
==========================================
- Coverage 90.25% 90.19% -0.06%
==========================================
Files 741 741
Lines 241207 242197 +990
Branches 45430 45719 +289
==========================================
+ Hits 217698 218456 +758
- Misses 15084 15239 +155
- Partials 8425 8502 +77
🚀 New features to boost your workflow:
|
Summary
Add a C++
buildHttpMessagehelper used by the HTTP/1.1 outgoing path so the common cases avoid repeated JavaScript string concatenation and multi-write overhead:_storeHeader: builds the status/request line + header block natively (with JS fallback for special cases such as content-disposition latin1 / unique cookie joining).ServerResponse.end()fast paths:writeHead():tryFastFlushEndflushes the prebuilt header + body without the fullwrite_()/ extra empty-write path (this is thebenchmark/http/simple.jscase)._headercompatibility.Public API and on-the-wire format are unchanged.
Benchmarks
Machine-local
out/Releaseon the same host. Baseline measured before this change.benchmark/http/simple.js(primary)Other
simple.jsvariants (same tip):chunkedEnc=1(TE: chunked)len=1024content-lengthOther microbenches
end-vs-write-endmethod=endasc/64 c=50 duration=5end-vs-write-endmethod=writeasc/64 c=50 duration=5res.end('ok')only (50 clients, 3s)Review feedback (document flags, no incidental C++ reformat, no
Buffer.concat) is included; the common ASCII path still shows the large win vs baseline.Tests
Full
test/parallel/test-http*suite: 751/751 passed (pre-push on an earlier tip); targeted suite re-run after the latest speed-ups.Test plan
tools/test.py test/parallel/test-http* --mode=release(751 passed)benchmark/http/simple.jsbefore/after (and after review + further speed-ups)