| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
Sorry, something went wrong.
There was a problem hiding this comment.
I remember we had a long discussion about this, I think for http. Have we ever come to a conclusion whether this is a good idea?
Sorry, something went wrong.
There was a problem hiding this comment.
The objects here are not exposed, so it's not an issue in this case.
Sorry, something went wrong.
There was a problem hiding this comment.
OK. And it does improve performance? Because - at least for me - it decreases readability.
Sorry, something went wrong.
There was a problem hiding this comment.
I didn't measure it specifically, but it does remove unnecessary hash table entries. It may also help if V8 sees only numeric keys being set on the object?
Sorry, something went wrong.
There was a problem hiding this comment.
@fhinkel Just curious. Do you mean using a Map instead of Object.create? #7581 (comment)
Sorry, something went wrong.
There was a problem hiding this comment.
For me it increases readability, but please check performance - I recall there being a regression when using .create(null) at one point.
Sorry, something went wrong.
There was a problem hiding this comment.
@Florian-R Thanks, that's the discussion I was thinking of. But in this case I meant {} vs .create(null).
Sorry, something went wrong.
There was a problem hiding this comment.
@benjamingr I'm not sure what regression you're referring to. These objects are created at startup, not during runtime, so the time to create them doesn't matter as much.
Sorry, something went wrong.
There was a problem hiding this comment.
I understand this is not about performance, but just out of curiosity, I measured the performance difference.
console.time("{}"); for (var i = 100000; i--;) { var a = {}; } console.timeEnd("{}"); var create = Object.create; console.time("create"); for (var i = 100000; i--;) { var b = create(null); } console.timeEnd("create");
{}: 5.792ms
create: 15.221ms
Probably, calling a function is heavier than {}
Sorry, something went wrong.
There was a problem hiding this comment.
Literals are always faster than instantiation and builder function calls, in JS and most languages.
Sorry, something went wrong.
There was a problem hiding this comment.
Thanks. I like this much better than using arguments.
Sorry, something went wrong.
There was a problem hiding this comment.
Can we check for typeof args1 == 'undefined' rather than using length? Or is undefined a valid value for args1?
Sorry, something went wrong.
There was a problem hiding this comment.
I would say it's a valid value.
Sorry, something went wrong.
There was a problem hiding this comment.
Thanks for the speedup. LGTM.
Sorry, something went wrong.
There was a problem hiding this comment.
Changes look good to me. Left one comment but it should not block merging.
Sorry, something went wrong.
There was a problem hiding this comment.
For me it increases readability, but please check performance - I recall there being a regression when using .create(null) at one point.
Sorry, something went wrong.
There was a problem hiding this comment.
Unsure why we'd want this in an extra function
Sorry, something went wrong.
There was a problem hiding this comment.
I think extracting it into a function increases readability.
Sorry, something went wrong.
There was a problem hiding this comment.
The main reason is to keep the insert() size down, but it does also help a bit with readability I suppose.
Sorry, something went wrong.
There was a problem hiding this comment.
...args ?
Sorry, something went wrong.
There was a problem hiding this comment.
Rest args are still slow.
Sorry, something went wrong.
There was a problem hiding this comment.
Great move.
Sorry, something went wrong.
There was a problem hiding this comment.
Why is this a new function?
Sorry, something went wrong.
There was a problem hiding this comment.
To keep function sizes down.
Sorry, something went wrong.
There was a problem hiding this comment.
IMHO, there's no repetead call, you add a short flow path (and creates a mini and fake cyclomatic complexity), function is in the same script and right under the function (so you just added brackets and more names to read). Function call is slower than direct structured code (and even minimal performance gains, in this call stack queen, is important).
I would not do this separation.
Sorry, something went wrong.
There was a problem hiding this comment.
unsure if changing this won't have side-effects somewhere
Sorry, something went wrong.
There was a problem hiding this comment.
I grepped lib/ and ._repeat isn't used anywhere except timers.js.
Sorry, something went wrong.
There was a problem hiding this comment.
I'm more concerned about user code, I do understand that it is unlikely but it has been the way it was an awfully long time in the wild.
Sorry, something went wrong.
There was a problem hiding this comment.
Would you rather I leave the variable set to null since it wouldn't be used anymore and add a new property that stores the interval value?
Sorry, something went wrong.
There was a problem hiding this comment.
should only be timer._handle I think
Sorry, something went wrong.
There was a problem hiding this comment.
Unfortunately not, as _http_outgoing and net have a ._handle and manually enroll() pre-made objects. Node will crash since those ._handle instances are not only not Timeout instances, but they also do not have a .start() method.
Sorry, something went wrong.
There was a problem hiding this comment.
And the reason this change is necessary now is that the rearming code no longer has access to the scope where the Timeout instance was created.
Sorry, something went wrong.
There was a problem hiding this comment.
hmmmm ok
Sorry, something went wrong.
There was a problem hiding this comment.
i would just check if (timer._repeat) iirc that is what is done elsewhere.
Sorry, something went wrong.
There was a problem hiding this comment.
I don't think it's safe really since ._repeat is now being used to store the interval value, which would not work for the 0 interval.
Sorry, something went wrong.
There was a problem hiding this comment.
@mscdex you can't have an interval of 0. It becomes 1.
Sorry, something went wrong.
There was a problem hiding this comment.
Changed.
Sorry, something went wrong.
There was a problem hiding this comment.
I don't see any tangible benefit to doing this.
We only use Number value keys.
Sorry, something went wrong.
There was a problem hiding this comment.
As was previously mentioned, I didn't measure the change specifically, but it does remove unnecessary hash table entries. It may also help if V8 sees only numeric keys being set on the object? It has nothing to do with key name collisions in this case.
Sorry, something went wrong.
There was a problem hiding this comment.
LGTM
Sorry, something went wrong.
There was a problem hiding this comment.
if ontimeout() throws will it deo-opt that function?
Sorry, something went wrong.
There was a problem hiding this comment.
Which function? tryOnTimeout()? ontimeout()? The user's callback?
I don't know that throwing causes a deopt or not, but adding a try-* block certainly does cause a deopt for the containing function.
Sorry, something went wrong.
There was a problem hiding this comment.
but adding a try-* block certainly does cause a deopt for the containing function.
Right, which is why it was constrained to within one separate function.
I'm curious if a throw fork a user callback de-opts ontimeout() along the way though, since that could be somewhat unpleasant.
Maybe we shouldn't worry about it? Idk the sate of benchmarking this stuff is already so bad 😐
Sorry, something went wrong.
There was a problem hiding this comment.
I just wrote a little test and as far as I can tell a function (or any calling functions in the call stack) shouldn't get deopted if that function throws.
Sorry, something went wrong.
There was a problem hiding this comment.
Try deopt any container function. Node.js should, IMHO, always test for nullity and use flags/optionals and never try-catch in the inner functions... This pattern is not really a requirement in functional programming and there's huge performance benefits on native calls (basically, in any platform too. try-catch system is expensive).
Sorry, something went wrong.
There was a problem hiding this comment.
I'm more concerned about user code, I do understand that it is unlikely but it has been the way it was an awfully long time in the wild.
Sorry, something went wrong.
There was a problem hiding this comment.
It probably doesn't matter much, but you could use len here instead of arguments.length.
Sorry, something went wrong.
There was a problem hiding this comment.
Changed.
Sorry, something went wrong.
|
CI again after recent changes: https://ci.nodejs.org/job/node-test-pull-request/4188/ |
Sorry, something went wrong.
|
Still LGTM. |
Sorry, something went wrong.
|
@mscdex ... it would also be good to have a citgm run on this. |
Sorry, something went wrong.
Sorry, something went wrong.
|
citgm looks ok, osx and ppcle had a few npm install issues it seems though but that does not appear to be related to this PR. |
Sorry, something went wrong.
There was a problem hiding this comment.
LGTM
Sorry, something went wrong.
|
seems fine to me |
Sorry, something went wrong.
|
One last CI before landing: https://ci.nodejs.org/job/node-test-pull-request/4347/ EDIT: CI is green |
Sorry, something went wrong.
This commit improves timers performance by making functions inlineable and avoiding the creation of extra closures/functions. This commit also makes setTimeout/Interval argument handling consistent with that of setImmediate. These changes give ~22% improvement in the existing 'breadth' timers benchmark. PR-URL: nodejs#8661 Reviewed-By: Franziska Hinkelmann <franziska.hinkelmann@gmail.com> Reviewed-By: Benjamin Gruenbaum <benjamingr@gmail.com> Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Ilkka Myller <ilkka.myller@nodefield.com> Reviewed-By: Jeremiah Senkpiel <fishrock123@rocketmail.com>
This commit improves timers performance by making functions inlineable and avoiding the creation of extra closures/functions. This commit also makes setTimeout/Interval argument handling consistent with that of setImmediate. These changes give ~22% improvement in the existing 'breadth' timers benchmark. PR-URL: #8661 Reviewed-By: Franziska Hinkelmann <franziska.hinkelmann@gmail.com> Reviewed-By: Benjamin Gruenbaum <benjamingr@gmail.com> Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Ilkka Myller <ilkka.myller@nodefield.com> Reviewed-By: Jeremiah Senkpiel <fishrock123@rocketmail.com>
|
adding LTS watch for now, although it will need quite a bit of time to bake before landing. @mscdex do you see any reason we should not land it in the future? |
Sorry, something went wrong.
|
@thealphanerd No, it should be ok. |
Sorry, something went wrong.
This commit improves timers performance by making functions inlineable and avoiding the creation of extra closures/functions. This commit also makes setTimeout/Interval argument handling consistent with that of setImmediate. These changes give ~22% improvement in the existing 'breadth' timers benchmark. PR-URL: #8661 Reviewed-By: Franziska Hinkelmann <franziska.hinkelmann@gmail.com> Reviewed-By: Benjamin Gruenbaum <benjamingr@gmail.com> Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Ilkka Myller <ilkka.myller@nodefield.com> Reviewed-By: Jeremiah Senkpiel <fishrock123@rocketmail.com>
* fs: - `SyncWriteStream` now inherits from `Stream.Writable`. (Anna Henningsen) #8830 - Practically, this means that when stdio is piped to a file, stdout and stderr will still be `Writable` streams. - `fs.existsSync()` has been undeprecated. `fs.exists()` remains deprecated. (Dan Fabulich) #8364 * http: `http.request()` now accepts a `timeout` option. (Rene Weber) #8101 * module: The module loader now maintains its own realpath cache. (Anna Henningsen) #8100 * npm: Upgraded to 3.10.8 (Kat Marchán) #8706 * stream: `Duplex` streams now show proper `instanceof Stream.Writable`. (Anna Henningsen) #8834 * timers: Improved `setTimeout`/`Interval` performance by up to 22%. (Brian White) #8661 PR-URL: #9034
* fs: - `SyncWriteStream` now inherits from `Stream.Writable`. (Anna Henningsen) #8830 - Practically, this means that when stdio is piped to a file, stdout and stderr will still be `Writable` streams. - `fs.existsSync()` has been undeprecated. `fs.exists()` remains deprecated. (Dan Fabulich) #8364 * http: `http.request()` now accepts a `timeout` option. (Rene Weber) #8101 * module: The module loader now maintains its own realpath cache. (Anna Henningsen) #8100 * npm: Upgraded to 3.10.8 (Kat Marchán) #8706 * stream: `Duplex` streams now show proper `instanceof Stream.Writable`. (Anna Henningsen) #8834 * timers: Improved `setTimeout`/`Interval` performance by up to 22%. (Brian White) #8661 PR-URL: #9034
* fs:
- `SyncWriteStream` now inherits from `Stream.Writable`. (Anna
Henningsen) nodejs/node#8830
- Practically, this means that when stdio is piped to a file,
stdout and stderr will still be `Writable` streams.
- `fs.existsSync()` has been undeprecated. `fs.exists()` remains
deprecated. (Dan Fabulich) nodejs/node#8364
* http: `http.request()` now accepts a `timeout` option. (Rene Weber)
nodejs/node#8101
* module: The module loader now maintains its own realpath cache. (Anna
Henningsen) nodejs/node#8100
* npm: Upgraded to 3.10.8 (Kat Marchan)
nodejs/node#8706
* stream: `Duplex` streams now show proper `instanceof
Stream.Writable`. (Anna Henningsen)
nodejs/node#8834
* timers: Improved `setTimeout`/`Interval` performance by up to 22%.
(Brian White) nodejs/node#8661
Signed-off-by: Ilkka Myller <ilkka.myller@nodefield.com>
* fs:
- `SyncWriteStream` now inherits from `Stream.Writable`. (Anna
Henningsen) nodejs/node#8830
- Practically, this means that when stdio is piped to a file,
stdout and stderr will still be `Writable` streams.
- `fs.existsSync()` has been undeprecated. `fs.exists()` remains
deprecated. (Dan Fabulich) nodejs/node#8364
* http: `http.request()` now accepts a `timeout` option. (Rene Weber)
nodejs/node#8101
* module: The module loader now maintains its own realpath cache. (Anna
Henningsen) nodejs/node#8100
* npm: Upgraded to 3.10.8 (Kat Marchan)
nodejs/node#8706
* stream: `Duplex` streams now show proper `instanceof
Stream.Writable`. (Anna Henningsen)
nodejs/node#8834
* timers: Improved `setTimeout`/`Interval` performance by up to 22%.
(Brian White) nodejs/node#8661
Signed-off-by: Ilkka Myller <ilkka.myller@nodefield.com>
There was a problem hiding this comment.
There's some point to enhance. Object.create is bad at that first lines (literal is faster than Object.create() and I do not see real memory benefits).
There's space for micro optimizations, but the overall improvements are great and makes the commit rich enough.
Sorry, something went wrong.
There was a problem hiding this comment.
Literals are always faster than instantiation and builder function calls, in JS and most languages.
Sorry, something went wrong.
There was a problem hiding this comment.
Try deopt any container function. Node.js should, IMHO, always test for nullity and use flags/optionals and never try-catch in the inner functions... This pattern is not really a requirement in functional programming and there's huge performance benefits on native calls (basically, in any platform too. try-catch system is expensive).
Sorry, something went wrong.
There was a problem hiding this comment.
Great move.
Sorry, something went wrong.
There was a problem hiding this comment.
IMHO, there's no repetead call, you add a short flow path (and creates a mini and fake cyclomatic complexity), function is in the same script and right under the function (so you just added brackets and more names to read). Function call is slower than direct structured code (and even minimal performance gains, in this call stack queen, is important).
I would not do this separation.
Sorry, something went wrong.
|
|
||
| function unrefdHandle() { | ||
| this.owner._onTimeout(); | ||
| ontimeout(this.owner); |
There was a problem hiding this comment.
This is always better for internal workings. ALWAYS, Node community.
Avoid this, globals, function calls, function separation in minimal pieces and inner functions... and we'll always have fine code with max JS performance.
Sorry, something went wrong.
|
@leodutra this was already merged. If you want, you could submit a new PR. |
Sorry, something went wrong.
|
I think performance-related improvements to try/catch/finally landed in v8 54. |
Sorry, something went wrong.
| Back | FazBrowse Home | New Git URL |
Checklist
Affected core subsystem(s)
Description of change
This commit improves timers performance by making functions inlineable and avoiding the creation of extra closures/functions.
This commit also makes setTimeout/Interval argument handling consistent with that of setImmediate.
These changes give ~22% improvement in the existing 'breadth' timers benchmark.