Debugging: name every function #8913
Description
Activity
This applies to 4.x & master. I did not check 6.x, I assume 6.x and master are the same.
- addedhttpIssues and PRs related to the http subsystem.Issues and PRs related to the http subsystem.good first issueIssues that are suitable for first-time contributors.Issues that are suitable for first-time contributors.
on Oct 3, 2016 We can't name arrow functions though. Since those are done for perf reasons you'd still need to live with them... :/
@Fishrock123 out of curiosity (pardon if this venue isn't suited for inquiry); pre-assigning the arrow function before usage does retain the naming while
--inspect:ing - is what you're referring to not to do due to performance hits?@fl0w you mean assigning to a variable means you get the variable name? You can't assign names to arrow functions like to regular functions though.
const a = () => 42; a.name; // returns 'a'
works since V8 5.1, so that should be possible.
Reacted by Miguel Angel Asencio Hurtado, jacob kili, MK (fengmk2), Pedro Victor, Moritz Mahringer, Dan Levy, Aditya Anand M C, Steven, Zachariah Garcia and Josu Goñi@Fishrock123 @addaleax answered before me - I was wondering if that was an overhead you were referring to in your original comment.
koajs/koa#805 (comment) for pictures
Do you have a link to a demonstration that arrows are more performant. I suspect named function declarations would be more performant then arrow functions.
V8 doesn't have to worry about super and new.target when emitting code for arrow functions.
It's a minor thing and probably not much of an issue once the function makes it to the optimizing tier but it means that core should lean towards arrow functions, all other things being equal.
@Raynos anywhere where
bind/thispassing was/is necessary.Other than that, they are only marginally different like @bnoordhuis said. The best rule of thumb is use them where you need the lexical
thisand regular functions elsewhere. (Which is exactly what we do.)Thanks for input @Fishrock123 @bnoordhuis Agreed that
bindis bad.I wrote a quick benchmark ( https://github.com/proxy/gist.github.com/Raynos/93d275463a90306b4b0779fed308550c ).
I ran the benchmark with node 6.4.0 & v8 5.0.71 and performance of both arrows and closures is identical.Having a named function declaration;
var self = this; function someName() { self.wat() }Instead of
() => self.wat()will still improve heap debugging.I suspect using a technique that improves heap introspection is more valuable then saving a few lines of code. Especially if the allocation and calling performance of both is the same.
In your benchmark the arrow/non-arrow functions are optimized almost right from the start but that's not very representative of long tail code (code that gets called periodically but not frequently enough to get optimized.)
var self = thisis something I definitely recommend against.() => this.wat()captures just the lexicalthisbut the function in your example can over-capture the enclosing lexical scope due to how V8 implements closures. If you had avar big = Buffer(1 << 28)in there, it could stay alive as long as the function.It's not a theoretical concern either. Over the years I've fixed several memory leaks in core that were the result of over-capturing.
- Reacted by mary marchini, Trivikram Kamat, Steven, Alison Monteiro and Brandon PattersonReacted by Mark Herhold, David Trejo, Viktor Karpov, Pedro Victor, Sean Vieira, Steven, Zachariah Garcia, wishtrip-dev and Austin ZielinskiReacted by Scott Santucci, Steven and Travis FischerReacted by Scott Santucci
@soleboxy I’d suggest picking a file in
lib/, doing it, opening a PR and seeing how that goes. A single pull request for all functions across all JS files would basically be a recipe for conflicts. If you’re unsure about anything, feel free to ask here or in #node-dev on Freenode! :)241 remaining items
Load more actionsI agree with @addaleax and I think our situation improved significantly since this issue was opened. Not only have we named almost all functions throughout the code but the compiler will now infer the the names very well by now.
Therefore I am going to close this as resolved. If someone disagrees, please feel free to reopen. However, even if this is closed, it should of course not keep someone from opening a PR that provides names to functions that can not be inferred.
Reacted by Miguel Angel Asencio Hurtado, Julien Gilli and antsmartian- added 2 commits that reference this issue
on Jul 18, 2018 - added 2 commits that reference this issue
on Jul 18, 2018 - added a commit that references this issue
on Aug 4, 2018 - added a commit that references this issue
on Aug 6, 2018

There are too many anonymous functions in the source code which makes heap debugging frustrating
This
once('response')listener ( https://github.com/nodejs/node/blob/master/lib/_http_client.js#L235-L237 ) is anonymous.When I try to debug why I am leaking
responselisteners in a heap snapshotI see that the
listenerin theonceclosure isfunction () {}which gives me no information. I strongly suspect that it's theabortlistener but i have no evidence for it.There are many, many, many anonymous functions in node core, there should be zero.