feat(stream): make Readable.from performance better#37609
feat(stream): make Readable.from performance better#37609wwwzbwcom wants to merge 11 commits intonodejs:masterfrom wwwzbwcom:master
Conversation
|
Thanks, I'm not sure I entirely understand this change and the for loop - will comment inline also cc @nodejs/streams |
lib/internal/streams/from.js
Outdated
| if (isAysnc) { | ||
| r = await iterator.next(); | ||
| } else { | ||
| r = iterator.next(); |
There was a problem hiding this comment.
The change here is that iterator.next() with a sync iterator is not awaited and if there are multiple next calls it is pushed directly without waiting for the next next?
There was a problem hiding this comment.
if the iterator is not async, it's not neccessary to await it
|
Any benchmark? |
|
I think it would be more readable to split this into two separate methods, i.e. |
|
@ronag pun intended 😅 ? |
|
Thanks for so much help. |
Here is a simple benchmark shows that prevent unecessary await can bring more than 5x faster performance: Code: 'use strict';
async function bench() {
console.time('await');
for (let i = 0; i < 1e8; i++) {
let a = await i;
}
console.timeEnd('await');
console.time('no await');
for (let i = 0; i < 1e8; i++) {
let a = i;
}
console.timeEnd('no await');
console.time('check await');
for (let i = 0; i < 1e8; i++) {
if (i === Promise.resolve(i)) {
let a = await i;
} else {
let a = i;
}
}
console.timeEnd('check await');
}
bench();Result: await: 6.409s
no await: 77.315ms
check await: 1.266sAlso, loop always bring better time and space performance compares to recursive. |
benjamingr
left a comment
There was a problem hiding this comment.
I am generally fine with this - thanks :)
- The PromiseResolve probably bit needs to be amended to work with third-party thenables
- Since this is a performance PR - I want to see a benchmark so we know this actually improves performance.
- This definitely needs a CITGM run IMO since it changes the timings of
Readable.fromin non-trivial ways.
Once there is a benchmark (let me know) I'll start a CITGM run, if you want help with setting the benchmark up - feel free to ask any questions or ask for assistance here :)
@benjamingr Thanks for your advice I think I know how to write a benchmark, but dont know how to let the benchmark compare between current and the earlier version of code. Should I benchmark earlier version manually and post the result, or there is a better way? |
What does |
There's a guide on how to create a benchmark here: How to compare different node versions here: There are also some |
await implicitly calls |
Co-authored-by: Robert Nagy <ronagy@icloud.com>
@benjamingr Hello, I add the benchmark, looks like it has a 30% improvement here's the result: # Run bechmark
node benchmark/compare.js --old ./node-master --new ./node-dev --filter "readable-from" streams > compare-pr-dev.csv
cat compare-dev.csv | Rscript benchmark/compare.R
# Result
Warning message:
In as.POSIXlt.POSIXct(Sys.time()) :
unknown timezone 'default/Asia/Shanghai'
confidence improvement accuracy (*) (**) (***)
streams/readable-from.jsn=10000000 *** 30.15 % ±4.32% ±5.76% ±7.52%
Be aware that when doing many comparisons the risk of a false-positive
result increases. In this case, there are 1 comparisons, you can thus
expect the following amount of false-positive results:
0.05 false positives, when considering a 5% risk acceptance (*, **, ***),
0.01 false positives, when considering a 1% risk acceptance (**, ***),
0.00 false positives, when considering a 0.1% risk acceptance (***) |
|
One last comment |
@benjamingr Where is the comment, I can't find it |
|
@benjamingr check for thenable has fixed ;) |
I cant find the relation between failing checks and my changes, can anyone help me figure out? Thanks :) |
|
@wwwzbwcom it looks like CITGM pipeline were red for months already, might be nothing to worry about 😬 |
|
Thank you for your contribution and patience. Let's hope this doesn't break too much :) Please note the naming convention for the future :) (Which is subsystem: change and not semantic commits) Landed in 2c251ff 🎉 |
PR-URL: #37609 Reviewed-By: Robert Nagy <ronagy@icloud.com> Reviewed-By: Benjamin Gruenbaum <benjamingr@gmail.com> Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
PR-URL: #37609 Reviewed-By: Robert Nagy <ronagy@icloud.com> Reviewed-By: Benjamin Gruenbaum <benjamingr@gmail.com> Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
| bench.start(); | ||
| s.on('data', (data) => { | ||
| // eslint-disable-next-line no-unused-expressions | ||
| data; |
Uh oh!
There was an error while loading. Please reload this page.