Repository navigation
Use collectBody in the JsonPost example - #1347
Conversation
Benchmark:
|
| Scenario | Base req/s | Head req/s | Head / base | Rounds | Noise | Busy | CPU per request |
|---|---|---|---|---|---|---|---|
| http/hello-world | 140851 | 140329 | 0.997x (-0.3%) | 0.99 to 1.00 | ±2.0% | 100% / 100% | 7.09 / 7.12 us (1.003x) |
| http/headers | 119313 | 119378 | 1.001x (+0.1%) | 1.00 to 1.01 | ±1.3% | 100% / 100% | 8.37 / 8.37 us (0.999x) |
| http/json-post | 110109 | 109303 | 0.993x (-0.7%) | 0.98 to 1.00 | ±0.9% | 100% / 100% | 9.07 / 9.14 us (1.007x) |
| http/cached | 157669 | 157669 | 1.000x (-0.0%) | 0.99 to 1.00 | ±1.0% | 100% / 100% | 6.34 / 6.34 us (1.000x) |
| ws/echo-20b | 146394 | 145483 | 0.993x (-0.7%) | 0.99 to 1.00 | ±1.2% | 100% / 100% | 6.82 / 6.87 us (1.007x) |
| ws/echo-4kb | 127548 | 128069 | 1.001x (+0.1%) | 0.98 to 1.02 | ±3.5% | 100% / 100% | 7.83 / 7.80 us (0.999x) |
4 rounds of 3s per scenario, each round loading base, head and a second process of each one, from a copy of its build, after the other, in an order that changes every round. "Head / base" is the median of the per-round ratios of req/s and "Rounds" their range. "Noise" is how far base/base and head/head, the same code on both sides, got from 1 in this same run: that is what the machine did, so a row is marked only when the median moved further than that, at least 2%, and every round moved the same way: 👀 slower, 🏆 faster. "Busy" is the cpu time of the server process over the round and "CPU per request" that time divided by the requests it answered, with the head/base ratio judged against its own same-code band and bold when it cleared it. When busy is well under 100% the load generator set the pace, the req/s are its and the cpu per request is the column to read. Only the ratios are comparable across runs, the absolute figures depend on the runner.
Node v26.10.0, AMD EPYC 9V74 80-Core Processor, 4 cores (server on cpu 0, load on 2,3), http_load_test and load_test with 100 connections.
|
It could be interesting to implement that collectJson promise you mentioned in another thread: v8::JSON::Parse is available in C++ and could be called by the library itself, directly returning the JSON object. Or if Promises are too slow, at least a CB based collectJSON that uses v8::JSON::Parse to directly give you the thing. A benchmark for that, and some testing could be interesting maybe it is faster? |
|
Yep, I made a PoC. |
The JsonPost example reads the body with onData and a Buffer.concat for every chunk, in about 35 lines. res.collectBody does the same natively since March: one buffer in C++, and null when the body is over a limit. So readJson becomes a few lines.
This also answers #1346: the readJson it asks for is already in the library, as collectBody.
One difference: the example now closes the connection on a body over 1 MB, before it had no limit.
Tested on v20.71.0: small JSON, 600 KB in 40 pieces, invalid JSON, empty body and a client that closes in the middle give the same result as before; a 2 MB body is now refused.