On Fri, Jun 8, 2012 at 7:23 PM, Jimb Esser <[email protected]> wrote:
> [Moved to nodejs instead of nodejs-dev since this is of general interest > and only tangental to the original request] > > I've never thought of using .bind instead of .call, but since .bind does > allocate something, and .call theoretically doesn't have to, I'd just > assume .call is more efficient, though I've learned any performance > assumptions about JS are usually incorrect ^_^. > > Doing a quick jsperf test of the things discussed here: > http://jsperf.com/bind-vs-call2 > Results are... questionable, and I don't put too much stock in micro-tests > like this, as the optimizer is good at making them go fast in inconsistent > ways. But, anyway, f.call(o) is way faster than f.bind(o)(), which is not > surprising. Slightly surprising, .bind seems to underperform closures > significantly in this case, though (at least on the older version of V8 > node is using), in real-world apps (at least, ours), I'm pretty certain > .bind is generally better... also allocates less memory (although in a > micro-test like this V8 likely effectively optimizes out any memory > allocations from the no-op closures). > This comparison is unbalanced -- when would you ever bind() more then once? The bound function cannot be rebound. Furthermore, when would you ever bind() and immediately execute? Never - because the correct approach is to use call() when immediate invocation is required. bind() is one shot deal that returns a new bound function to be called later. Rick > > - Jimb Esser > > On Fri, Jun 8, 2012 at 3:14 PM, AJ ONeal <[email protected]> wrote: > >> Interesting. So have you found bind() to be more or less efficient than >> .call() and or .apply()? >> >> AJ ONeal >> >> >> On Fri, Jun 8, 2012 at 3:48 PM, Jimb Esser <[email protected]> wrote: >> >>> Technically, at least in V8, .bind is a lot lighter weight than an >>> anonymous function. There are a large number of micro-benchmarks to look >>> at on jsperf.com, but for an actual anecdote, at one point we >>> accidentally required in a module which overrode Function.prototype.bind >>> with something that created an anonymous function (some browser-support >>> code for pre-.bind browsers), and our performance tanked, garbage >>> collection times increased significantly. >>> >>> >>> On Fri, Jun 8, 2012 at 2:25 PM, AJ ONeal <[email protected]> wrote: >>> >>>> If I'm not mistaken, bind() has the same technical drawbacks as using >>>> an anonymous function (higher memory usage, more garbage collection, and >>>> slower says Tim), but it does solve the maintainability / prettiness issue. >>>> >>>> I just want to point out that Raspberry Pi is now shipping. >>>> NodeJS is a very attractive option for development. >>>> >>>> My own experience with my ARM-based media server has lead me to be a >>>> believer in prototypes and leaner code. I can't say that one little anony >>>> here and there is going to blow up an application, but I know for a fact >>>> that there are significant performance gains when they are avoided. >>>> >>>> I know it doesn't seem like a big deal now. But one day you may change >>>> your mind. >>>> >>>> AJ ONeal >>>> >>>> On Fri, Jun 8, 2012 at 2:22 PM, George Stagas <[email protected]>wrote: >>>> >>>>> No need to change the API, we have .bind() - use the language >>>>> features, don't reinvent them. >>>>> >>>>> 2012/6/8 Tim Caswell <[email protected]>: >>>>> > >>>>> > >>>>> > On Fri, Jun 8, 2012 at 2:10 PM, tjholowaychuk < >>>>> [email protected]> >>>>> > wrote: >>>>> >> >>>>> >> what's wrong with .bind() ? >>>>> >> >>>>> > >>>>> > Mainly the overhead. Bind creates a new function every time it's >>>>> called, >>>>> > and calling the bound function is a bit slower, especially in V8. >>>>> (Insert >>>>> > statement about performance only mattering if it's significant...) >>>>> > >>>>> > I usually will bind all my methods from the prototype that will be >>>>> used as >>>>> > callbacks to the instance itself inside the constructor. This gives >>>>> me a >>>>> > ton more "own" properties, but otherwise is fairly elegant. >>>>> > >>>>> >> >>>>> >> On Jun 8, 11:52 am, AJ ONeal <[email protected]> wrote: >>>>> >> > emitter.on('data', myModule.dataHandler, myModule); >>>>> >> > >>>>> >> > Even if myModule were to subclass EventEmitter, wouldn't I still >>>>> need to >>>>> >> > pass in the `myModule` instance so that I get the correct `this`? >>>>> I >>>>> >> > don't >>>>> >> > think I understood what you meant by that. >>>>> >> > >>>>> >> > And then these cases as well: >>>>> >> > >>>>> >> > fs.readFile(file, encoding, myModule.fileHandler, myModule); >>>>> >> > >>>>> >> > process.nextTick(myModule.tickHandler, myModule); >>>>> >> > >>>>> >> > The list goes on. Obviously not a small project. Not difficult >>>>> either, >>>>> >> > just >>>>> >> > tedious. >>>>> >> > >>>>> >> > AJ ONeal >>>>> >> > >>>>> >> > >>>>> >> > >>>>> >> > >>>>> >> > >>>>> >> > >>>>> >> > >>>>> >> > On Fri, Jun 8, 2012 at 12:42 PM, Tim Caswell <[email protected] >>>>> > >>>>> >> > wrote: >>>>> >> > > Actually event emitters already call in the scope of the >>>>> emitter, so >>>>> >> > > there >>>>> >> > > is no need for a specific "this" value there. Just subclass >>>>> >> > > EventEmitter >>>>> >> > > and use normal methods. >>>>> >> > >>>>> >> > > On Fri, Jun 8, 2012 at 1:34 PM, AJ ONeal <[email protected]> >>>>> wrote: >>>>> >> > >>>>> >> > >> If you're going to use `this` then you must have a callback. >>>>> It would >>>>> >> > >> make no sense to have a `this` and nothing to apply it to. >>>>> >> > >>>>> >> > >> You think EventEmitters would feel the overhead of the if? >>>>> >> > >>>>> >> > >> // context is Array, Object, or Function. >>>>> >> > >> // Numbers, Strings, and Booleans need not `apply` (very >>>>> punny) >>>>> >> > >> if (context) { >>>>> >> > >> fn.call(context, a, b, c); >>>>> >> > >> } else { >>>>> >> > >> fn(a, b, c); >>>>> >> > >> } >>>>> >> > >>>>> >> > >> As far as the guesswork, well, I hear you on that. I've >>>>> already done >>>>> >> > >> my >>>>> >> > >> ranting at UtahJS Conf. Put this as one more in the bucket of >>>>> reasons >>>>> >> > >> that >>>>> >> > >> callbacks-last was not a well-thought out idea.... >>>>> >> > >>>>> >> > >> AJ ONeal >>>>> >> > >>>>> >> > >> On Fri, Jun 8, 2012 at 12:27 PM, Tim Caswell < >>>>> [email protected]> >>>>> >> > >> wrote: >>>>> >> > >>>>> >> > >>> I think it's a useful addition, but it does cause a little >>>>> overhead >>>>> >> > >>> (though it's probably not noticeable compared to the actual >>>>> work the >>>>> >> > >>> async >>>>> >> > >>> function is doing). EventEmitters might feel the pain since >>>>> they >>>>> >> > >>> are sync. >>>>> >> > >>> I do worry that it makes things harder for our argument >>>>> guessing >>>>> >> > >>> code that >>>>> >> > >>> assumes the last arg is a callback. Now there will be an >>>>> optional >>>>> >> > >>> argument >>>>> >> > >>> after the callback that can be anything (including another >>>>> function) >>>>> >> > >>>>> >> > >>> On Fri, Jun 8, 2012 at 1:18 PM, AJ ONeal <[email protected]> >>>>> wrote: >>>>> >> > >>>>> >> > >>>> Yes, That's what I am suggesting. >>>>> >> > >>>>> >> > >>>> AJ ONeal >>>>> >> > >>>>> >> > >>>> On Fri, Jun 8, 2012 at 12:17 PM, Tim Caswell >>>>> >> > >>>> <[email protected]>wrote: >>>>> >> > >>>>> >> > >>>>> So this proposal is to modify the API of all async >>>>> functions to >>>>> >> > >>>>> have >>>>> >> > >>>>> an extra thisp argument after the callback argument (like >>>>> done in >>>>> >> > >>>>> Array.prototype.forEach)? >>>>> >> > >>>>> >> > >>>>> On Fri, Jun 8, 2012 at 1:06 PM, AJ ONeal < >>>>> [email protected]> >>>>> >> > >>>>> wrote: >>>>> >> > >>>>> >> > >>>>>> I would like to propose that an additional parameter, >>>>> `context` >>>>> >> > >>>>>> be >>>>> >> > >>>>>> added to core node modules that accept callbacks to give >>>>> >> > >>>>>> this-ness to the >>>>> >> > >>>>>> callback. >>>>> >> > >>>>> >> > >>>>>> The reason being is that I'm trying to eliminate anonymous >>>>> >> > >>>>>> callbacks >>>>> >> > >>>>>> from my code and have generally cleaner, more readable >>>>> code (as >>>>> >> > >>>>>> well as >>>>> >> > >>>>>> lower memory usage and less garbage collection). >>>>> >> > >>>>> >> > >>>>>> I don't know if this has been discussed before, but I'd >>>>> like to >>>>> >> > >>>>>> put >>>>> >> > >>>>>> it on the table. >>>>> >> > >>>>> >> > >>>>>> AJ ONeal >>>>> > >>>>> > >>>>> >>>> >>>> >>> >> > -- > Job Board: http://jobs.nodejs.org/ > Posting guidelines: > https://github.com/joyent/node/wiki/Mailing-List-Posting-Guidelines > You received this message because you are subscribed to the Google > Groups "nodejs" group. > To post to this group, send email to [email protected] > To unsubscribe from this group, send email to > [email protected] > For more options, visit this group at > http://groups.google.com/group/nodejs?hl=en?hl=en > -- Job Board: http://jobs.nodejs.org/ Posting guidelines: https://github.com/joyent/node/wiki/Mailing-List-Posting-Guidelines You received this message because you are subscribed to the Google Groups "nodejs" group. To post to this group, send email to [email protected] To unsubscribe from this group, send email to [email protected] For more options, visit this group at http://groups.google.com/group/nodejs?hl=en?hl=en
