GeezerVisonThe World Wide Web, restored to 800 pixels of glory. | |||||||||||
| Home|About|Gaming cabinet|Archives|How it works|Starter sites | |||||||||||
GeezerVison is showing github.com — http: improve performance for end() with known-length string by pimterry · Pull Request #65466 · nodejs/node Conversation
Member
When you call When the length is known and This drops a nextTick, and goes from 2 write calls to 1 for the very common case of In practice, in the tiny benchmark here which I think represents a very common use case (small API responses) I see this boosting HTTP RPS by up to 9% for writes up to 1KB or so. For larger responses the response write time starts to outweigh this, but I still see 3% RPS boost at 16KB. Needs autocannon to hit the rates required, you can test yourself with: node benchmark/compare.js --old ./node-main --new ./node-pr --runs 20 --set benchmarker=autocannon --filter end-string http Added a new test confirming the specific details and edge cases this touches, and updated one existing test which specifically asserted that
Sorry, something went wrong. Uh oh!
There was an error while loading. Please reload this page. All reactions
This boosts RPS performance for the common API case where you call `res.end(data)` with the entire response by up to 9%. Signed-off-by: Tim Perry <[email protected]>
Collaborator
All reactions
Sorry, something went wrong. Uh oh!
There was an error while loading. Please reload this page.
mcollina
approved these changes
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. lgtm
Sorry, something went wrong. Uh oh!
There was an error while loading. Please reload this page. All reactions
anonrig
approved these changes
|
There was an error while loading. Please reload this page.
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@ ## main #65466 +/- ## ========================================== - Coverage 90.14% 90.13% -0.01% ========================================== Files 751 751 Lines 252298 252333 +35 Branches 47446 47449 +3 ========================================== + Hits 227436 227451 +15 - Misses 16175 16186 +11 - Partials 8687 8696 +9
🚀 New features to boost your workflow:
|
Sorry, something went wrong.
There was an error while loading. Please reload this page.
Sorry, something went wrong.
There was an error while loading. Please reload this page.
|
@bjohansebas benchmark label was a good suggestion. I've done a run here. Unfortunately it seems like the microbenchmark job is broken generally (cc @nodejs/build) and all recent jobs have failed with: I've manually extracted the CSV from the console output to get some numbers though, and run Detailsconfidence improvement accuracy (*) (**) (***) http/bench-parser-fragmented.js n=100000 frags=2 len=16 -0.20 % ±1.06% ±1.42% ±1.85% http/bench-parser-fragmented.js n=100000 frags=2 len=8 -0.01 % ±0.94% ±1.25% ±1.63% http/bench-parser-fragmented.js n=100000 frags=4 len=16 -0.17 % ±0.77% ±1.02% ±1.33% http/bench-parser-fragmented.js n=100000 frags=4 len=8 -0.57 % ±0.64% ±0.85% ±1.11% http/bench-parser-fragmented.js n=100000 frags=8 len=16 -0.07 % ±0.84% ±1.12% ±1.45% http/bench-parser-fragmented.js n=100000 frags=8 len=8 0.43 % ±0.78% ±1.04% ±1.35% http/bench-parser.js n=100000 len=16 0.20 % ±0.93% ±1.24% ±1.61% http/bench-parser.js n=100000 len=32 0.03 % ±0.68% ±0.90% ±1.17% http/bench-parser.js n=100000 len=4 0.60 % ±1.08% ±1.43% ±1.86% http/bench-parser.js n=100000 len=8 0.32 % ±1.11% ±1.47% ±1.92% http/check_invalid_header_char.js n=1000000 input='' 1.25 % ±2.48% ±3.30% ±4.30% http/check_invalid_header_char.js n=1000000 input='\t\t\t\t\t\t\t\t\t\tFoo bar baz' 0.39 % ±1.66% ±2.21% ±2.88% http/check_invalid_header_char.js n=1000000 input='\x7F' * 4.92 % ±3.90% ±5.19% ±6.75% http/check_invalid_header_char.js n=1000000 input='1' -0.41 % ±3.47% ±4.62% ±6.02% http/check_invalid_header_char.js n=1000000 input='20091' -0.50 % ±3.85% ±5.12% ±6.66% http/check_invalid_header_char.js n=1000000 input='close' 0.49 % ±3.34% ±4.44% ±5.78% http/check_invalid_header_char.js n=1000000 input='en-US' -0.66 % ±3.59% ±4.77% ±6.21% http/check_invalid_header_char.js n=1000000 input='foo\nbar' -1.88 % ±2.70% ±3.60% ±4.70% http/check_invalid_header_char.js n=1000000 input='group_acmeair' 0.85 % ±1.82% ±2.42% ±3.16% http/check_invalid_header_char.js n=1000000 input='gzip' -0.60 % ±3.29% ±4.37% ±5.70% http/check_invalid_header_char.js n=1000000 input='keep-alive' -1.28 % ±2.16% ±2.88% ±3.75% http/check_invalid_header_char.js n=1000000 input='LONG_AND_INVALID' 0.08 % ±1.13% ±1.51% ±1.97% http/check_invalid_header_char.js n=1000000 input='private' 1.00 % ±2.68% ±3.57% ±4.65% http/check_invalid_header_char.js n=1000000 input='SAMEORIGIN' 1.36 % ±2.81% ±3.74% ±4.88% http/check_invalid_header_char.js n=1000000 input='Sat, 07 May 2016 16:54:48 GMT' 0.79 % ±1.41% ±1.87% ±2.44% http/check_invalid_header_char.js n=1000000 input='text/html; charset=utf-8' -0.12 % ±1.41% ±1.88% ±2.45% http/check_invalid_header_char.js n=1000000 input='text/plain' -1.49 % ±2.96% ±3.95% ±5.14% http/check_invalid_header_char.js n=1000000 input='中文呢' 1.95 % ±2.71% ±3.61% ±4.69% http/check_is_http_token.js n=1000000 key=':' -0.22 % ±2.22% ±2.96% ±3.85% http/check_is_http_token.js n=1000000 key=':alternate-protocol' 2.82 % ±4.07% ±5.42% ±7.06% http/check_is_http_token.js n=1000000 key='((((())))' -1.22 % ±2.75% ±3.71% ±4.91% http/check_is_http_token.js n=1000000 key='@@' 0.52 % ±2.14% ±2.85% ±3.71% http/check_is_http_token.js n=1000000 key='Accept-Ranges' 0.51 % ±2.25% ±2.99% ±3.90% http/check_is_http_token.js n=1000000 key='alt-svc' -0.09 % ±2.23% ±2.97% ±3.87% http/check_is_http_token.js n=1000000 key='alternate-protocol:' -0.94 % ±2.08% ±2.77% ±3.61% http/check_is_http_token.js n=1000000 key='alternate-protocol' -1.19 % ±2.32% ±3.09% ±4.03% http/check_is_http_token.js n=1000000 key='Cache-Control' -0.96 % ±2.14% ±2.85% ±3.71% http/check_is_http_token.js n=1000000 key='Connection' 0.78 % ±2.39% ±3.19% ±4.15% http/check_is_http_token.js n=1000000 key='Content-Encoding' * -2.76 % ±2.26% ±3.01% ±3.92% http/check_is_http_token.js n=1000000 key='content-length' 0.93 % ±2.27% ±3.02% ±3.92% http/check_is_http_token.js n=1000000 key='Content-Location' -0.15 % ±2.52% ±3.35% ±4.36% http/check_is_http_token.js n=1000000 key='content-type' -0.49 % ±2.55% ±3.39% ±4.41% http/check_is_http_token.js n=1000000 key='Content-Type' 0.46 % ±2.58% ±3.43% ±4.47% http/check_is_http_token.js n=1000000 key='date' 0.62 % ±2.42% ±3.22% ±4.19% http/check_is_http_token.js n=1000000 key='ETag' -2.60 % ±3.97% ±5.32% ±7.01% http/check_is_http_token.js n=1000000 key='Expires' ** 3.69 % ±2.64% ±3.52% ±4.59% http/check_is_http_token.js n=1000000 key='Keep-Alive' -0.03 % ±2.59% ±3.45% ±4.48% http/check_is_http_token.js n=1000000 key='Last-Modified' -0.99 % ±2.34% ±3.12% ±4.07% http/check_is_http_token.js n=1000000 key='location' 0.79 % ±2.44% ±3.25% ±4.23% http/check_is_http_token.js n=1000000 key='server' 0.37 % ±2.46% ±3.27% ±4.25% http/check_is_http_token.js n=1000000 key='Server' * 3.70 % ±3.00% ±4.00% ±5.23% http/check_is_http_token.js n=1000000 key='status' ** -4.32 % ±3.09% ±4.13% ±5.40% http/check_is_http_token.js n=1000000 key='TCN' -0.86 % ±1.00% ±1.33% ±1.73% http/check_is_http_token.js n=1000000 key='Transfer-Encoding' -1.00 % ±2.32% ±3.09% ±4.02% http/check_is_http_token.js n=1000000 key='Vary' -0.56 % ±1.47% ±1.95% ±2.54% http/check_is_http_token.js n=1000000 key='version' 1.90 % ±2.74% ±3.65% ±4.75% http/check_is_http_token.js n=1000000 key='x-frame-options' 0.57 % ±2.05% ±2.73% ±3.55% http/check_is_http_token.js n=1000000 key='x-xss-protection' -1.39 % ±2.29% ±3.06% ±3.99% http/check_is_http_token.js n=1000000 key='中文呢' -1.00 % ±4.47% ±6.01% ±7.92% http/chunked.js duration=5 c=100 len=1 n=1 benchmarker='wrk' -0.19 % ±0.68% ±0.91% ±1.18% http/chunked.js duration=5 c=100 len=1 n=16 benchmarker='wrk' 0.41 % ±0.78% ±1.03% ±1.35% http/chunked.js duration=5 c=100 len=1 n=4 benchmarker='wrk' 0.61 % ±2.08% ±2.76% ±3.60% http/chunked.js duration=5 c=100 len=1 n=8 benchmarker='wrk' 0.13 % ±0.81% ±1.07% ±1.40% http/chunked.js duration=5 c=100 len=256 n=1 benchmarker='wrk' -0.10 % ±0.70% ±0.93% ±1.21% http/chunked.js duration=5 c=100 len=256 n=16 benchmarker='wrk' -0.70 % ±0.73% ±0.97% ±1.26% http/chunked.js duration=5 c=100 len=256 n=4 benchmarker='wrk' -0.58 % ±1.84% ±2.45% ±3.18% http/chunked.js duration=5 c=100 len=256 n=8 benchmarker='wrk' 0.11 % ±0.87% ±1.16% ±1.51% http/chunked.js duration=5 c=100 len=64 n=1 benchmarker='wrk' -0.26 % ±0.60% ±0.80% ±1.04% http/chunked.js duration=5 c=100 len=64 n=16 benchmarker='wrk' 0.56 % ±0.63% ±0.84% ±1.10% http/chunked.js duration=5 c=100 len=64 n=4 benchmarker='wrk' 0.08 % ±1.81% ±2.41% ±3.15% http/chunked.js duration=5 c=100 len=64 n=8 benchmarker='wrk' 0.26 % ±0.75% ±1.00% ±1.30% http/client-request-body.js method='end' len=1024 type='asc' dur=5 -0.06 % ±0.69% ±0.92% ±1.20% http/client-request-body.js method='end' len=1024 type='buf' dur=5 0.01 % ±0.76% ±1.02% ±1.32% http/client-request-body.js method='end' len=1024 type='utf' dur=5 -0.28 % ±0.59% ±0.79% ±1.03% http/client-request-body.js method='end' len=256 type='asc' dur=5 -0.49 % ±0.67% ±0.90% ±1.17% http/client-request-body.js method='end' len=256 type='buf' dur=5 * -0.75 % ±0.68% ±0.90% ±1.18% http/client-request-body.js method='end' len=256 type='utf' dur=5 0.03 % ±0.62% ±0.83% ±1.08% http/client-request-body.js method='end' len=32 type='asc' dur=5 -0.01 % ±0.56% ±0.75% ±0.98% http/client-request-body.js method='end' len=32 type='buf' dur=5 -0.37 % ±0.60% ±0.79% ±1.03% http/client-request-body.js method='end' len=32 type='utf' dur=5 -0.16 % ±0.62% ±0.83% ±1.08% http/client-request-body.js method='write' len=1024 type='asc' dur=5 -0.16 % ±0.78% ±1.03% ±1.34% http/client-request-body.js method='write' len=1024 type='buf' dur=5 -0.34 % ±0.68% ±0.90% ±1.17% http/client-request-body.js method='write' len=1024 type='utf' dur=5 0.06 % ±0.78% ±1.04% ±1.35% http/client-request-body.js method='write' len=256 type='asc' dur=5 0.27 % ±0.70% ±0.93% ±1.21% http/client-request-body.js method='write' len=256 type='buf' dur=5 0.09 % ±0.76% ±1.02% ±1.32% http/client-request-body.js method='write' len=256 type='utf' dur=5 0.49 % ±0.59% ±0.79% ±1.03% http/client-request-body.js method='write' len=32 type='asc' dur=5 -0.40 % ±0.64% ±0.86% ±1.11% http/client-request-body.js method='write' len=32 type='buf' dur=5 -0.21 % ±0.65% ±0.86% ±1.12% http/client-request-body.js method='write' len=32 type='utf' dur=5 0.02 % ±0.60% ±0.79% ±1.03% http/cluster.js duration=5 c=50 len=1024 type='buffer' benchmarker='wrk' 0.13 % ±0.46% ±0.62% ±0.81% http/cluster.js duration=5 c=50 len=1024 type='bytes' benchmarker='wrk' -0.11 % ±0.38% ±0.50% ±0.66% http/cluster.js duration=5 c=50 len=102400 type='buffer' benchmarker='wrk' -0.24 % ±0.49% ±0.65% ±0.85% http/cluster.js duration=5 c=50 len=102400 type='bytes' benchmarker='wrk' 0.14 % ±0.80% ±1.06% ±1.38% http/cluster.js duration=5 c=50 len=4 type='buffer' benchmarker='wrk' -0.23 % ±0.29% ±0.39% ±0.51% http/cluster.js duration=5 c=50 len=4 type='bytes' benchmarker='wrk' 0.00 % ±0.51% ±0.67% ±0.88% http/cluster.js duration=5 c=500 len=1024 type='buffer' benchmarker='wrk' ** -0.77 % ±0.50% ±0.67% ±0.87% http/cluster.js duration=5 c=500 len=1024 type='bytes' benchmarker='wrk' -0.18 % ±0.65% ±0.86% ±1.12% http/cluster.js duration=5 c=500 len=102400 type='buffer' benchmarker='wrk' -0.18 % ±0.59% ±0.78% ±1.02% http/cluster.js duration=5 c=500 len=102400 type='bytes' benchmarker='wrk' 0.28 % ±0.72% ±0.95% ±1.24% http/cluster.js duration=5 c=500 len=4 type='buffer' benchmarker='wrk' -0.25 % ±0.47% ±0.62% ±0.81% http/cluster.js duration=5 c=500 len=4 type='bytes' benchmarker='wrk' -0.36 % ±0.52% ±0.70% ±0.91% http/create-clientrequest.js e=1 arg='options' url='idn' 2.09 % ±7.80% ±10.38% ±13.50% http/create-clientrequest.js e=1 arg='options' url='long' -9.98 % ±14.10% ±18.77% ±24.46% http/create-clientrequest.js e=1 arg='options' url='wpt' -4.69 % ±6.75% ±8.98% ±11.70% http/create-clientrequest.js e=1 arg='string' url='idn' -4.15 % ±10.23% ±13.61% ±17.71% http/create-clientrequest.js e=1 arg='string' url='long' -0.93 % ±12.77% ±16.99% ±22.12% http/create-clientrequest.js e=1 arg='string' url='wpt' 0.60 % ±11.36% ±15.12% ±19.68% http/create-clientrequest.js e=1 arg='URL' url='idn' 0.87 % ±9.17% ±12.20% ±15.88% http/create-clientrequest.js e=1 arg='URL' url='long' -5.01 % ±10.02% ±13.35% ±17.41% http/create-clientrequest.js e=1 arg='URL' url='wpt' 1.99 % ±8.00% ±10.64% ±13.85% http/end-string.js duration=5 c=50 len=1024 benchmarker='wrk' *** 10.48 % ±0.81% ±1.08% ±1.41% http/end-string.js duration=5 c=50 len=102400 benchmarker='wrk' *** 2.47 % ±0.50% ±0.66% ±0.86% http/end-string.js duration=5 c=50 len=16384 benchmarker='wrk' *** 5.59 % ±0.89% ±1.19% ±1.55% http/end-string.js duration=5 c=50 len=4 benchmarker='wrk' *** 9.92 % ±0.82% ±1.10% ±1.43% http/end-string.js duration=5 c=50 len=64 benchmarker='wrk' *** 8.43 % ±0.71% ±0.94% ±1.23% http/end-vs-write-end.js duration=5 method='end' c=100 len=1048576 type='asc' benchmarker='wrk' *** 2.48 % ±0.47% ±0.62% ±0.81% http/end-vs-write-end.js duration=5 method='end' c=100 len=1048576 type='buf' benchmarker='wrk' -0.12 % ±0.43% ±0.57% ±0.74% http/end-vs-write-end.js duration=5 method='end' c=100 len=1048576 type='utf' benchmarker='wrk' *** 0.68 % ±0.38% ±0.51% ±0.66% http/end-vs-write-end.js duration=5 method='end' c=100 len=131072 type='asc' benchmarker='wrk' ** 1.19 % ±0.81% ±1.09% ±1.43% http/end-vs-write-end.js duration=5 method='end' c=100 len=131072 type='buf' benchmarker='wrk' *** 1.50 % ±0.59% ±0.78% ±1.01% http/end-vs-write-end.js duration=5 method='end' c=100 len=131072 type='utf' benchmarker='wrk' *** 2.25 % ±0.45% ±0.59% ±0.77% http/end-vs-write-end.js duration=5 method='end' c=100 len=262144 type='asc' benchmarker='wrk' *** 1.18 % ±0.42% ±0.56% ±0.73% http/end-vs-write-end.js duration=5 method='end' c=100 len=262144 type='buf' benchmarker='wrk' *** 0.92 % ±0.48% ±0.63% ±0.83% http/end-vs-write-end.js duration=5 method='end' c=100 len=262144 type='utf' benchmarker='wrk' *** 1.25 % ±0.32% ±0.43% ±0.56% http/end-vs-write-end.js duration=5 method='end' c=100 len=65536 type='asc' benchmarker='wrk' *** 1.60 % ±0.83% ±1.10% ±1.44% http/end-vs-write-end.js duration=5 method='end' c=100 len=65536 type='buf' benchmarker='wrk' *** 2.34 % ±0.88% ±1.18% ±1.53% http/end-vs-write-end.js duration=5 method='end' c=100 len=65536 type='utf' benchmarker='wrk' *** 2.95 % ±0.48% ±0.64% ±0.83% http/end-vs-write-end.js duration=5 method='write' c=100 len=1048576 type='asc' benchmarker='wrk' -0.33 % ±0.57% ±0.77% ±1.00% http/end-vs-write-end.js duration=5 method='write' c=100 len=1048576 type='buf' benchmarker='wrk' -0.16 % ±0.52% ±0.69% ±0.90% http/end-vs-write-end.js duration=5 method='write' c=100 len=1048576 type='utf' benchmarker='wrk' -0.12 % ±0.36% ±0.47% ±0.62% http/end-vs-write-end.js duration=5 method='write' c=100 len=131072 type='asc' benchmarker='wrk' 0.07 % ±0.76% ±1.01% ±1.32% http/end-vs-write-end.js duration=5 method='write' c=100 len=131072 type='buf' benchmarker='wrk' -0.25 % ±0.51% ±0.68% ±0.89% http/end-vs-write-end.js duration=5 method='write' c=100 len=131072 type='utf' benchmarker='wrk' 0.53 % ±1.00% ±1.34% ±1.74% http/end-vs-write-end.js duration=5 method='write' c=100 len=262144 type='asc' benchmarker='wrk' -0.26 % ±0.61% ±0.81% ±1.06% http/end-vs-write-end.js duration=5 method='write' c=100 len=262144 type='buf' benchmarker='wrk' -0.05 % ±0.47% ±0.62% ±0.81% http/end-vs-write-end.js duration=5 method='write' c=100 len=262144 type='utf' benchmarker='wrk' -0.08 % ±0.56% ±0.74% ±0.96% http/end-vs-write-end.js duration=5 method='write' c=100 len=65536 type='asc' benchmarker='wrk' -0.50 % ±0.96% ±1.28% ±1.66% http/end-vs-write-end.js duration=5 method='write' c=100 len=65536 type='buf' benchmarker='wrk' -0.22 % ±0.71% ±0.94% ±1.23% http/end-vs-write-end.js duration=5 method='write' c=100 len=65536 type='utf' benchmarker='wrk' 0.10 % ±0.58% ±0.77% ±1.01% http/headers.js group='fewHeaders' duration=5 len=1 n=10 benchmarker='wrk' -0.23 % ±0.65% ±0.86% ±1.13% http/headers.js group='fewHeaders' duration=5 len=5 n=10 benchmarker='wrk' 0.25 % ±0.59% ±0.79% ±1.03% http/headers.js group='manyHeaders' duration=5 len=1 n=600 benchmarker='wrk' -0.11 % ±0.86% ±1.15% ±1.49% http/headers.js group='manyHeaders' duration=5 len=100 n=600 benchmarker='wrk' 0.22 % ±1.12% ±1.49% ±1.94% http/headers.js group='mediumHeaders' duration=5 len=1 n=50 benchmarker='wrk' -0.28 % ±0.51% ±0.67% ±0.88% http/headers.js group='mediumHeaders' duration=5 len=10 n=50 benchmarker='wrk' 0.04 % ±0.53% ±0.71% ±0.93% http/http_server_for_chunky_client.js type='send' n=2000 len=1 0.19 % ±0.57% ±0.77% ±1.00% http/http_server_for_chunky_client.js type='send' n=2000 len=128 -0.12 % ±0.59% ±0.78% ±1.02% http/http_server_for_chunky_client.js type='send' n=2000 len=16 -0.01 % ±0.60% ±0.79% ±1.03% http/http_server_for_chunky_client.js type='send' n=2000 len=32 0.15 % ±0.61% ±0.81% ±1.06% http/http_server_for_chunky_client.js type='send' n=2000 len=4 0.67 % ±0.69% ±0.92% ±1.21% http/http_server_for_chunky_client.js type='send' n=2000 len=64 -0.30 % ±0.48% ±0.64% ±0.83% http/http_server_for_chunky_client.js type='send' n=2000 len=8 -0.50 % ±0.55% ±0.73% ±0.95% http/http_server_for_chunky_client.js type='send' n=5 len=1 -1.39 % ±2.60% ±3.47% ±4.51% http/http_server_for_chunky_client.js type='send' n=5 len=128 -4.15 % ±13.02% ±17.32% ±22.54% http/http_server_for_chunky_client.js type='send' n=5 len=16 7.54 % ±10.05% ±13.50% ±17.81% http/http_server_for_chunky_client.js type='send' n=5 len=32 0.87 % ±11.95% ±15.91% ±20.71% http/http_server_for_chunky_client.js type='send' n=5 len=4 1.73 % ±10.57% ±14.06% ±18.30% http/http_server_for_chunky_client.js type='send' n=5 len=64 -5.12 % ±14.17% ±18.86% ±24.56% http/http_server_for_chunky_client.js type='send' n=5 len=8 -2.55 % ±5.92% ±7.90% ±10.32% http/http_server_for_chunky_client.js type='send' n=50 len=1 1.27 % ±2.86% ±3.81% ±4.96% http/http_server_for_chunky_client.js type='send' n=50 len=128 * 5.17 % ±4.13% ±5.49% ±7.15% http/http_server_for_chunky_client.js type='send' n=50 len=16 -0.71 % ±2.69% ±3.58% ±4.67% http/http_server_for_chunky_client.js type='send' n=50 len=32 -0.12 % ±2.72% ±3.63% ±4.74% http/http_server_for_chunky_client.js type='send' n=50 len=4 -1.47 % ±3.06% ±4.07% ±5.29% http/http_server_for_chunky_client.js type='send' n=50 len=64 2.04 % ±3.51% ±4.67% ±6.09% http/http_server_for_chunky_client.js type='send' n=50 len=8 -0.08 % ±2.21% ±2.94% ±3.84% http/http_server_for_chunky_client.js type='send' n=500 len=1 -0.08 % ±0.80% ±1.07% ±1.40% http/http_server_for_chunky_client.js type='send' n=500 len=128 -0.38 % ±0.70% ±0.93% ±1.21% http/http_server_for_chunky_client.js type='send' n=500 len=16 * -0.94 % ±0.83% ±1.11% ±1.45% http/http_server_for_chunky_client.js type='send' n=500 len=32 -0.43 % ±0.83% ±1.11% ±1.45% http/http_server_for_chunky_client.js type='send' n=500 len=4 -0.02 % ±0.71% ±0.95% ±1.24% http/http_server_for_chunky_client.js type='send' n=500 len=64 -0.19 % ±0.93% ±1.24% ±1.62% http/http_server_for_chunky_client.js type='send' n=500 len=8 -0.15 % ±0.71% ±0.95% ±1.23% http/incoming_headers.js duration=5 w=0 headers=20 connections=50 benchmarker='wrk' 0.04 % ±0.81% ±1.08% ±1.42% http/incoming_headers.js duration=5 w=6 headers=20 connections=50 benchmarker='wrk' 0.04 % ±0.64% ±0.85% ±1.11% http/set_header.js n=1000000 value='Connection' ** -2.20 % ±1.65% ±2.19% ±2.85% http/set_header.js n=1000000 value='Content-Length' 0.29 % ±1.71% ±2.28% ±2.97% http/set_header.js n=1000000 value='Content-Type' 1.33 % ±1.88% ±2.51% ±3.27% http/set_header.js n=1000000 value='Set-Cookie' 1.14 % ±1.33% ±1.77% ±2.30% http/set_header.js n=1000000 value='Transfer-Encoding' 1.06 % ±1.33% ±1.76% ±2.30% http/set_header.js n=1000000 value='Vary' -0.57 % ±1.72% ±2.29% ±2.99% http/set_header.js n=1000000 value='X-Powered-By' * 1.49 % ±1.33% ±1.77% ±2.30% http/set-header.js duration=5 res='normal' benchmarker='wrk' *** 9.74 % ±0.78% ±1.04% ±1.35% http/set-header.js duration=5 res='setHeader' benchmarker='wrk' *** 9.87 % ±0.83% ±1.10% ±1.44% http/set-header.js duration=5 res='setHeaderWH' benchmarker='wrk' *** 9.59 % ±0.92% ±1.22% ±1.59% http/simple.js duration=5 chunkedEnc=0 c=50 chunks=1 len=1024 type='buffer' benchmarker='wrk' *** 2.60 % ±0.75% ±1.00% ±1.30% http/simple.js duration=5 chunkedEnc=0 c=50 chunks=1 len=1024 type='bytes' benchmarker='wrk' *** 9.54 % ±0.74% ±0.99% ±1.28% http/simple.js duration=5 chunkedEnc=0 c=50 chunks=1 len=102400 type='buffer' benchmarker='wrk' ** 1.23 % ±0.75% ±0.99% ±1.29% http/simple.js duration=5 chunkedEnc=0 c=50 chunks=1 len=102400 type='bytes' benchmarker='wrk' *** 1.98 % ±0.49% ±0.65% ±0.84% http/simple.js duration=5 chunkedEnc=0 c=50 chunks=1 len=4 type='buffer' benchmarker='wrk' *** 2.43 % ±0.76% ±1.01% ±1.31% http/simple.js duration=5 chunkedEnc=0 c=50 chunks=1 len=4 type='bytes' benchmarker='wrk' *** 9.55 % ±0.71% ±0.95% ±1.24% http/simple.js duration=5 chunkedEnc=0 c=50 chunks=4 len=1024 type='buffer' benchmarker='wrk' *** 3.14 % ±0.86% ±1.15% ±1.50% http/simple.js duration=5 chunkedEnc=0 c=50 chunks=4 len=1024 type='bytes' benchmarker='wrk' *** 2.94 % ±0.78% ±1.04% ±1.35% http/simple.js duration=5 chunkedEnc=0 c=50 chunks=4 len=102400 type='buffer' benchmarker='wrk' *** 1.55 % ±0.62% ±0.82% ±1.07% http/simple.js duration=5 chunkedEnc=0 c=50 chunks=4 len=102400 type='bytes' benchmarker='wrk' ** 1.10 % ±0.82% ±1.09% ±1.42% http/simple.js duration=5 chunkedEnc=0 c=50 chunks=4 len=4 type='buffer' benchmarker='wrk' *** 3.91 % ±0.83% ±1.10% ±1.44% http/simple.js duration=5 chunkedEnc=0 c=50 chunks=4 len=4 type='bytes' benchmarker='wrk' *** 3.47 % ±0.93% ±1.23% ±1.60% http/simple.js duration=5 chunkedEnc=0 c=500 chunks=1 len=1024 type='buffer' benchmarker='wrk' *** 3.60 % ±0.96% ±1.27% ±1.66% http/simple.js duration=5 chunkedEnc=0 c=500 chunks=1 len=1024 type='bytes' benchmarker='wrk' *** 9.20 % ±0.99% ±1.32% ±1.72% http/simple.js duration=5 chunkedEnc=0 c=500 chunks=1 len=102400 type='buffer' benchmarker='wrk' *** 1.28 % ±0.53% ±0.71% ±0.93% http/simple.js duration=5 chunkedEnc=0 c=500 chunks=1 len=102400 type='bytes' benchmarker='wrk' *** 1.28 % ±0.65% ±0.87% ±1.13% http/simple.js duration=5 chunkedEnc=0 c=500 chunks=1 len=4 type='buffer' benchmarker='wrk' *** 3.59 % ±0.96% ±1.28% ±1.67% http/simple.js duration=5 chunkedEnc=0 c=500 chunks=1 len=4 type='bytes' benchmarker='wrk' *** 9.93 % ±1.01% ±1.35% ±1.76% http/simple.js duration=5 chunkedEnc=0 c=500 chunks=4 len=1024 type='buffer' benchmarker='wrk' *** 2.04 % ±0.98% ±1.31% ±1.70% http/simple.js duration=5 chunkedEnc=0 c=500 chunks=4 len=1024 type='bytes' benchmarker='wrk' *** 2.14 % ±0.82% ±1.08% ±1.41% http/simple.js duration=5 chunkedEnc=0 c=500 chunks=4 len=102400 type='buffer' benchmarker='wrk' *** 1.74 % ±0.67% ±0.89% ±1.16% http/simple.js duration=5 chunkedEnc=0 c=500 chunks=4 len=102400 type='bytes' benchmarker='wrk' ** 1.10 % ±0.79% ±1.05% ±1.36% http/simple.js duration=5 chunkedEnc=0 c=500 chunks=4 len=4 type='buffer' benchmarker='wrk' *** 3.20 % ±0.94% ±1.24% ±1.62% http/simple.js duration=5 chunkedEnc=0 c=500 chunks=4 len=4 type='bytes' benchmarker='wrk' *** 3.12 % ±0.76% ±1.01% ±1.32% http/simple.js duration=5 chunkedEnc=1 c=50 chunks=1 len=1024 type='buffer' benchmarker='wrk' -0.19 % ±0.80% ±1.06% ±1.38% http/simple.js duration=5 chunkedEnc=1 c=50 chunks=1 len=1024 type='bytes' benchmarker='wrk' -0.44 % ±0.95% ±1.26% ±1.65% http/simple.js duration=5 chunkedEnc=1 c=50 chunks=1 len=102400 type='buffer' benchmarker='wrk' 0.11 % ±0.61% ±0.81% ±1.06% http/simple.js duration=5 chunkedEnc=1 c=50 chunks=1 len=102400 type='bytes' benchmarker='wrk' * -1.19 % ±1.11% ±1.47% ±1.92% http/simple.js duration=5 chunkedEnc=1 c=50 chunks=1 len=4 type='buffer' benchmarker='wrk' -0.23 % ±0.80% ±1.07% ±1.39% http/simple.js duration=5 chunkedEnc=1 c=50 chunks=1 len=4 type='bytes' benchmarker='wrk' 0.10 % ±0.75% ±1.00% ±1.30% http/simple.js duration=5 chunkedEnc=1 c=50 chunks=4 len=1024 type='buffer' benchmarker='wrk' -0.55 % ±0.76% ±1.01% ±1.32% http/simple.js duration=5 chunkedEnc=1 c=50 chunks=4 len=1024 type='bytes' benchmarker='wrk' 0.19 % ±0.95% ±1.27% ±1.65% http/simple.js duration=5 chunkedEnc=1 c=50 chunks=4 len=102400 type='buffer' benchmarker='wrk' ** -1.32 % ±0.79% ±1.06% ±1.37% http/simple.js duration=5 chunkedEnc=1 c=50 chunks=4 len=102400 type='bytes' benchmarker='wrk' 0.69 % ±1.07% ±1.42% ±1.85% http/simple.js duration=5 chunkedEnc=1 c=50 chunks=4 len=4 type='buffer' benchmarker='wrk' 0.54 % ±0.81% ±1.07% ±1.40% http/simple.js duration=5 chunkedEnc=1 c=50 chunks=4 len=4 type='bytes' benchmarker='wrk' 0.56 % ±0.71% ±0.95% ±1.23% http/simple.js duration=5 chunkedEnc=1 c=500 chunks=1 len=1024 type='buffer' benchmarker='wrk' -0.48 % ±0.80% ±1.07% ±1.39% http/simple.js duration=5 chunkedEnc=1 c=500 chunks=1 len=1024 type='bytes' benchmarker='wrk' -0.62 % ±0.85% ±1.13% ±1.48% http/simple.js duration=5 chunkedEnc=1 c=500 chunks=1 len=102400 type='buffer' benchmarker='wrk' -0.20 % ±0.69% ±0.92% ±1.20% http/simple.js duration=5 chunkedEnc=1 c=500 chunks=1 len=102400 type='bytes' benchmarker='wrk' 0.43 % ±1.18% ±1.56% ±2.04% http/simple.js duration=5 chunkedEnc=1 c=500 chunks=1 len=4 type='buffer' benchmarker='wrk' 0.29 % ±0.89% ±1.19% ±1.55% http/simple.js duration=5 chunkedEnc=1 c=500 chunks=1 len=4 type='bytes' benchmarker='wrk' * -1.01 % ±0.80% ±1.07% ±1.39% http/simple.js duration=5 chunkedEnc=1 c=500 chunks=4 len=1024 type='buffer' benchmarker='wrk' -0.18 % ±0.68% ±0.90% ±1.18% http/simple.js duration=5 chunkedEnc=1 c=500 chunks=4 len=1024 type='bytes' benchmarker='wrk' 0.09 % ±0.65% ±0.86% ±1.12% http/simple.js duration=5 chunkedEnc=1 c=500 chunks=4 len=102400 type='buffer' benchmarker='wrk' * -0.55 % ±0.49% ±0.66% ±0.86% http/simple.js duration=5 chunkedEnc=1 c=500 chunks=4 len=102400 type='bytes' benchmarker='wrk' 0.10 % ±0.82% ±1.09% ±1.42% http/simple.js duration=5 chunkedEnc=1 c=500 chunks=4 len=4 type='buffer' benchmarker='wrk' 0.35 % ±0.74% ±0.98% ±1.28% http/simple.js duration=5 chunkedEnc=1 c=500 chunks=4 len=4 type='bytes' benchmarker='wrk' -0.26 % ±0.65% ±0.86% ±1.12% http/upgrade.js n=1000 0.73 % ±2.37% ±3.16% ±4.11% http/upgrade.js n=5 6.72 % ±8.30% ±11.05% ±14.38% Looks good I think. Headlines:
Looks pretty convincing to me! All approved and ready-to-go now and I think this is all just good news, so I'll commit-queue. |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was an error while loading. Please reload this page.
|
Landed in 214cf06 |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
This boosts RPS performance for the common API case where you call `res.end(data)` with the entire response by up to 9%. Signed-off-by: Tim Perry <[email protected]> PR-URL: #65466 Reviewed-By: Matteo Collina <[email protected]> Reviewed-By: Yagiz Nizipli <[email protected]> Reviewed-By: Luigi Pinca <[email protected]> Reviewed-By: Gürgün Dayıoğlu <[email protected]>
This boosts RPS performance for the common API case where you call `res.end(data)` with the entire response by up to 9%. Signed-off-by: Tim Perry <[email protected]> PR-URL: #65466 Reviewed-By: Matteo Collina <[email protected]> Reviewed-By: Yagiz Nizipli <[email protected]> Reviewed-By: Luigi Pinca <[email protected]> Reviewed-By: Gürgün Dayıoğlu <[email protected]>
This boosts RPS performance for the common API case where you call `res.end(data)` with the entire response by up to 9%. Signed-off-by: Tim Perry <[email protected]> PR-URL: #65466 Reviewed-By: Matteo Collina <[email protected]> Reviewed-By: Yagiz Nizipli <[email protected]> Reviewed-By: Luigi Pinca <[email protected]> Reviewed-By: Gürgün Dayıoğlu <[email protected]>
This boosts RPS performance for the common API case where you call `res.end(data)` with the entire response by up to 9%. Signed-off-by: Tim Perry <[email protected]> PR-URL: #65466 Reviewed-By: Matteo Collina <[email protected]> Reviewed-By: Yagiz Nizipli <[email protected]> Reviewed-By: Luigi Pinca <[email protected]> Reviewed-By: Gürgün Dayıoğlu <[email protected]>
This boosts RPS performance for the common API case where you call `res.end(data)` with the entire response by up to 9%. Signed-off-by: Tim Perry <[email protected]> PR-URL: #65466 Reviewed-By: Matteo Collina <[email protected]> Reviewed-By: Yagiz Nizipli <[email protected]> Reviewed-By: Luigi Pinca <[email protected]> Reviewed-By: Gürgün Dayıoğlu <[email protected]>
Nodefony écrivait ses réponses en deux temps — `res.write(corps)` puis `end()` VIDE — là où Express les écrit en un seul `res.end(corps)`. Depuis Node 26.8 (nodejs/node#65466), cette différence de forme coûte un tick de boucle d'événements par réponse : `maybePrepareFinalChunk` n'est atteinte que si le corps est donné AU `end()`, et son commentaire l'annonce — « attach finish to the write to avoid a separate send() & tick step ». Mesuré de l'extérieur, machine et sandbox identiques, seule la version de Node changeant : Express encaisse -40,9 µs/req du passage de 26.7.0 à 26.8.1 quand Nodefony n'en encaisse que -32,9. Le rapport Nodefony/Express reste stable sous 26.7.0 (87,7 %) : ce n'est pas une régression, c'est un gain laissé passer. Trois lectures disaient trois choses : le changelog « known-length calls to end() », le titre du PR « known-length string », et le CODE `typeof chunk === 'string' || isUint8Array(chunk)` — donc un Buffer, ce que nous produisons. Rien ne nous excluait, sauf la forme de notre appel. Le streaming chunké (`flush()`) garde `write` + `drain` : la contre-pression n'a de sens que là, et la perdre exposerait la RAM du serveur à un client lent. Une réponse unique n'a rien à écrire ensuite. Gate mémoire vert et en NETTE amélioration (une Promise, une closure, un callback et un listener potentiel de moins par réponse) : 200 multipart 2,19 -> 0,27 MB, 500 mixtes 1,12 -> 0,20 MB, 1000 GET +0,42 -> -0,46 MB. 817 unitaires et 679 d'intégration verts. Le test neuf a été VU ROUGE en débranchant la condition, les trois cas du chemin chunké restant verts. Le chiffrage du gain se fera en A/B mono-prod sur la référence de banc propre (#397) : la fenêtre de ce soir a refusé 3 séries sur 4 pour dispersion. Refs #397 Co-Authored-By: Claude Opus 5 (1M context) <[email protected]> Claude-Session: https://claude.ai/code/session_01AaHTSgsBxd4m5EuhgfKX15
…runtime (#36) Node.js 24.21 and 26.8 (nodejs/node#65466) attach 'finish' to the final chunk of end(data) when that chunk can be the last write. Earlier releases write the chunk and then send a separate empty write that carries 'finish'. The socket sees one write in the new contract and two in the old one. Add HttpOutgoingEndPolicy so that an embedder can select the contract of the Node.js release that it targets. The default stays SeparateFinishWrite, which matches the Node.js release that Deno reports.
… callbacks Port of nodejs/node#64847 (v26.7.0) and nodejs/node#65466 (v26.8.0), so that OutgoingMessage and ServerResponse behave like Node.js v26.12.1: - writableFinished is a flag set just before 'finish', not a value computed from what is left to write. ServerResponse no longer has its own getter. - end() callbacks are queued instead of being 'finish' listeners. They run before 'finish' and get null, or the error that kept the bytes from leaving. A second end(cb) before 'finish' is queued too; ERR_STREAM_ALREADY_FINISHED is only given once the message has finished. - A response whose last write fails never emits 'finish': its callbacks get the error, stream.finished() reports a premature close and its request is aborted. - end(chunk) of known length attaches the finish step to its one write. The server's native and emit('connection') paths go through the same onFinish(). The 'http' performance entry and the trace span end at 'prefinish', where Node's ServerResponse#_finish() ends them, so that a response that never finishes still reports them. One deliberate difference: 'finish' is still emitted after an end() callback that throws. Node skips it, which leaves the connection stuck on that response.
There was an error while loading. Please reload this page.
Successfully merging this pull request may close these issues.
There was an error while loading. Please reload this page.