Re: [nodejs] Re: .bind performance (Was Re: context (thisness) to EventEmitter#on, process.nextTick, etc)

2012-06-08 Thread Rick Waldron

On Friday, June 8, 2012 at 8:29 PM, Jimb Esser wrote: 
> Binding more than once is very common 
> 
> 

The bound function returned by fn.bind cannot be rebound and will silently 
ignore any attempts to do so.

 
> - any code that is written with
> a closure instead can be written with a static function and a .bind
> (and, in general, be more efficient, causing less heap pressure).
> 
> 

I think you might be misusing terminology. Perhaps you could share a code 
example that illustrates your claim?

Rick
 
> 
> But, yeah, the immediate bind vs call was just in response to AJs
> query, and it's pretty clear there's no reason to do that
> (unless .bind was magically efficient, which it's not, it's just
> generally more efficient than a new closure).
> 
> 

 
> 
> On Jun 8, 5:22 pm, Rick Waldron  wrote:
> > On Fri, Jun 8, 2012 at 7:23 PM, Jimb Esser  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  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  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  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 
> > > > > > wrote:
> > 
> > > > > > > No need to change the API, we have .bind() - use the language
> > > > > > > features, don't reinvent them.
> > > > > > > 
> > > > > > 
> > > > > 
> > > > 
> > > 
> > 
> > 
> > > > > > > 2012/6/8 Tim Caswell :
> > 
> > > > > > > > On Fri, Jun 8, 2012 at 2:10 PM, tjhol

Re: [nodejs] Re: .bind performance (Was Re: context (thisness) to EventEmitter#on, process.nextTick, etc)

2012-06-08 Thread Tim Caswell
FWIW, my experience with .bind on V8 has always been that it's actually
significantly slower than just creating a closure yourself.  For a
microbenchmark, see http://jsperf.com/bind-vs-closure


Besides the memory overhead of using bind vs calling with call, bind has
strange semantics.  For example, many developers don't know that you can't
rebind a function.  It's rather opaque and weird.  I don't *like* working
with bound functions.  I do it many times anyway because the syntax is
rather pretty and the performance of that part isn't critical.



On Fri, Jun 8, 2012 at 7:34 PM, Rick Waldron  wrote:

>
>  On Friday, June 8, 2012 at 8:29 PM, Jimb Esser wrote:
>
> Binding more than once is very common
>
> The bound function returned by fn.bind cannot be rebound and will silently
> ignore any attempts to do so.
>
>
>
> - any code that is written with
> a closure instead can be written with a static function and a .bind
> (and, in general, be more efficient, causing less heap pressure).
>
> I think you might be misusing terminology. Perhaps you could share a code
> example that illustrates your claim?
>
> Rick
>
>
>
> But, yeah, the immediate bind vs call was just in response to AJs
> query, and it's pretty clear there's no reason to do that
> (unless .bind was magically efficient, which it's not, it's just
> generally more efficient than a new closure).
>
>
>
> On Jun 8, 5:22 pm, Rick Waldron  wrote:
>
> On Fri, Jun 8, 2012 at 7:23 PM, Jimb Esser  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  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  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  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 wrote:
>
>
> No need to change the API, we have .bind() - use the language
> features, don't reinvent them.
>
>
> 2012/6/8 Tim Caswell :
>
>
> On Fri, Jun 8, 2012 at 2:10 PM, tjholowaychuk <
>
> tjholoway...@gmail.com>
>
> 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.
>
> (Ins

Re: [nodejs] Re: .bind performance (Was Re: context (thisness) to EventEmitter#on, process.nextTick, etc)

2012-06-08 Thread Rick Waldron



On Saturday, June 9, 2012 at 12:21 AM, Jimb Esser wrote:

> By "binding more than once", I mean binding the same original function
> multiple times (with different parameters), not binding the result of
> a previously bound function.
>  
> An example of using bind instead of a closure:
> original:
> function backupFile(filename, cb) {
> fs.unlink(filename + '.bak', function(err) {
> fs.rename(filename, filename + '.bak', cb);
> });
> }
> Using bind and no run-time function creation:
> function backupFile(filename, cb) {
> fs.unlink(filename + '.bak', step2.bind(undefined, filename, cb));
> }
> function step2(filename, cb, err) {
> fs.rename(filename, filename + '.bak', cb);
> }
>  
I would agree that a function expression makes more sense in this case -- there 
is actually no reason to use bind() here at all. In fact, the comparison still 
doesn't balance because you're forcing bind() into a role that doesn't make 
sense. Additionally, this example is wantonly adding a function to the stack.  

bind()'s primary use case is passing one function's scope to another or 
"sharing" a "scope" (represented by an object) between with an unrelated 
functions.

Rick
  
>  
> Doing some microbenchmarks, it does seem, however, that the .bind
> version is allocating more memory (only using a little more on older
> V8 versions, but seems to be using over triple the amount of the
> closure on the V8 version in node 0.6.18), so I retract my earlier
> statement about bind generally being better performing. I was
> confusing the results of my anecdotal evidence, which was that
> implementing your own .bind function (or accidentally including a
> library that overrides Function.prototype.bind) is notably slower, but
> V8 seems good at optimizing closures in a local scope.
>  
> In theory the closure can also grab references to local variables in
> the scope, causing them not to get garbage collected as quickly, but
> in practice V8 seems to not grab references to the entire scope, just
> the appropriate objects.
>  
> On Jun 8, 5:34 pm, Rick Waldron  wrote:
> > On Friday, June 8, 2012 at 8:29 PM, Jimb Esser wrote:
> > > Binding more than once is very common
> >  
> >  
> > The bound function returned by fn.bind cannot be rebound and will silently 
> > ignore any attempts to do so.
> >  
> > > - any code that is written with
> > > a closure instead can be written with a static function and a .bind
> > > (and, in general, be more efficient, causing less heap pressure).
> > >  
> >  
> >  
> > I think you might be misusing terminology. Perhaps you could share a code 
> > example that illustrates your claim?
> >  
> > Rick
> >  
> >  
> >  
> >  
> >  
> >  
> >  
> >  
> >  
> > > But, yeah, the immediate bind vs call was just in response to AJs
> > > query, and it's pretty clear there's no reason to do that
> > > (unless .bind was magically efficient, which it's not, it's just
> > > generally more efficient than a new closure).
> > >  
> >  
> >  
> > > On Jun 8, 5:22 pm, Rick Waldron  wrote:
> > > > On Fri, Jun 8, 2012 at 7:23 PM, Jimb Esser  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.
> > > >  
> > >  
> >

Re: [nodejs] Re: .bind performance (Was Re: context (thisness) to EventEmitter#on, process.nextTick, etc)

2012-06-08 Thread Rick Waldron
>
> snip
>


> [1] https://gist.github.com/2899468
>
>
Nothing about the code in this gist actually needs to use bind(), but your
findings are certainly as expected - bind() actually creates a whole new
function object to return, whereas closing over with a function expression
or passing as arguments clearly do not.

Just a heads up, there is quite a bit of stack and invocation noise being
created in this example - a quick way to see this is by removing cb() and
cb.call(), you'll notice the values lower.



Rick

-- 
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 nodejs@googlegroups.com
To unsubscribe from this group, send email to
nodejs+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/nodejs?hl=en?hl=en


Re: [nodejs] Re: .bind performance (Was Re: context (thisness) to EventEmitter#on, process.nextTick, etc)

2012-06-10 Thread Alan Gutierrez

On 6/9/12 2:11 AM, Brandon Benvie wrote:

Part of the slowdown is because builtin bind has to handle construct as
well. But yeah, V8's bind is *notably* slow when you do a comparison of
either a full manual implementation of bind semantics yourself, or
compared to say Spidermonkey. I'm not sure what the deal is there, but
it *is* a V8 issue in some way or another.

For reference, this is the V8 bind code:
https://github.com/joyent/node/blob/master/deps/v8/src/v8natives.js#L1578


I was just reading up on `bind` versus closure performance. More 
discussion on all that `bind` does that a closure doesn't do here:


http://stackoverflow.com/questions/8656106/why-is-function-prototype-bind-slow

--
Alan - @bigeasy

--
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 nodejs@googlegroups.com
To unsubscribe from this group, send email to
nodejs+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/nodejs?hl=en?hl=en