Re: Why is .bind so slow?

2013-07-14 Thread Matthew Robb
function()-{},
Identical in every way to fat-arrow function except not lexically bound,
has access to arguments but not callee/caller, and can be call/applied. No
construct, supports no curlys, implicit return :D


On Sat, Jul 13, 2013 at 9:55 PM, Andrea Giammarchi 
andrea.giammar...@gmail.com wrote:

 not a part, I am imaging already a scenario where everyone will start
 avoiding `.bind()` in order to use arrow functions because these are faster
 ... something like:

 ```javascript
 obj.method = function () {
   return (e) = {
 // rest here
   };
 };
 node.addEventListener('evt', obj.method());
 ```

 ... I don't really like the approach ... can anyone think about a way to
 have arrowified functions at definition time? Will classes allow arrow
 functions magic inline ? nothing to bind anymore in this case ... different
 from the JS I know but that might work pretty well for performance ...
 although the prototype would be even more messed up ...





 On Sat, Jul 13, 2013 at 9:47 PM, Andrea Giammarchi 
 andrea.giammar...@gmail.com wrote:

 this makes more sense than `callee` since `.bind()` functions are slow
 even in `use strict` scenarios.

 However, I was not aware about the fact arrow functions have no arguments
 access at all ... between cool and limiting if you ask me but if
 performances are better then it's OK.

 Also OK would be to have a way to flag a function or a bound one static
 so that no `arguments` or `caller` will ever be available 'cause if this is
 the performance problem developers would love to have a better way to
 improve there.

 In the DOM world, as example, all bound functions accepts one single
 argument, the event object, while in node.js world basically all emitted
 functions accept 2 arguments and never/rarely more than two.

 As somebody said already in another thread, me, as developer, would love
 to help the JS engine to go faster where needed!

 Regards




 On Sat, Jul 13, 2013 at 12:39 PM, Mark S. Miller erig...@google.comwrote:

 Arrow functions, whether strict or non-strict, are not supposed to have
 their own |arguments|


 On Sat, Jul 13, 2013 at 11:55 AM, Jeff Walden jwalden...@mit.eduwrote:

 On 07/12/2013 04:59 PM, Andrea Giammarchi wrote:
  one more thing ... I believe this will impact arrow function too
 since is basically bound callbacks all over the place (or at least this is
 how I believe it will be transpiled)

 Sadly, based on the arrow-function patches I've reviewed in
 SpiderMonkey, I don't believe this will be necessarily true.  Arrow
 functions and bind-bound functions are two rather different beasts.
  Bind-bound functions are potentially constructible; arrow functions never
 are.  |arguments.callee| inside a function that's been bound doesn't refer
 to the bound function -- it refers to the lexical entity.  (That is,
 |function f() { return arguments.callee; } f.bind(null)()| is |f|, not
 |b|.)   |arguments.callee| inside an arrow function -- at least, so long as
 arrow functions aren't automatically strict, which decision I would revisit
 -- refers to the arrow function.  I expect there are other differences I'm
 not yet aware of, that would affect having a common implementation of the
 two concepts.

 It seems like a pretty bad idea to me for arrow functions to not be
 substantially semantically similar to bind-bound functions, but they are as
 it stands now.  I wish I had the time to sit down and think through a solid
 unification of the two concepts.

 Jeff
 ___
 es-discuss mailing list
 es-discuss@mozilla.org
 https://mail.mozilla.org/listinfo/es-discuss




 --
 Cheers,
 --MarkM




 ___
 es-discuss mailing list
 es-discuss@mozilla.org
 https://mail.mozilla.org/listinfo/es-discuss




-- 
- Matthew Robb
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Why is .bind so slow?

2013-07-13 Thread Jeff Walden
On 07/12/2013 04:59 PM, Andrea Giammarchi wrote:
 one more thing ... I believe this will impact arrow function too since is 
 basically bound callbacks all over the place (or at least this is how I 
 believe it will be transpiled)

Sadly, based on the arrow-function patches I've reviewed in SpiderMonkey, I 
don't believe this will be necessarily true.  Arrow functions and bind-bound 
functions are two rather different beasts.  Bind-bound functions are 
potentially constructible; arrow functions never are.  |arguments.callee| 
inside a function that's been bound doesn't refer to the bound function -- it 
refers to the lexical entity.  (That is, |function f() { return 
arguments.callee; } f.bind(null)()| is |f|, not |b|.)   |arguments.callee| 
inside an arrow function -- at least, so long as arrow functions aren't 
automatically strict, which decision I would revisit -- refers to the arrow 
function.  I expect there are other differences I'm not yet aware of, that 
would affect having a common implementation of the two concepts.

It seems like a pretty bad idea to me for arrow functions to not be 
substantially semantically similar to bind-bound functions, but they are as it 
stands now.  I wish I had the time to sit down and think through a solid 
unification of the two concepts.

Jeff
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Why is .bind so slow?

2013-07-13 Thread Jeff Walden
On 07/12/2013 02:54 PM, Allen Wirfs-Brock wrote:
 Looking at it another way, if implementation haven't found it straightforward 
 to optimize ES5 bound functions why would you expect that would have an 
 easier time with Proxys?

I'm pretty sure no implementation has seriously tried to optimize bound 
functions, and that that's the major reason for any slowness.  I don't think 
there's anything fundamentally difficult about optimizing bound functions.  
It's just never been a priority for engines, because it doesn't show up in 
benchmarks and because the perf bugs for it are less pressing than other perf 
work is, as bound functions remain underused on the web.  Chicken and egg?  
Sure.

In the meantime, while I wouldn't currently question (as a purely pragmatic 
choice) avoiding bind in highly intensive code where every bit of perf matters, 
I do think bound functions are fast enough for the vast majority of cases.  The 
overhead of calling a bound function will rarely be the difference between 
adequate and inadequate performance.

Jeff
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Why is .bind so slow?

2013-07-13 Thread David Bruant

Le 13/07/2013 20:55, Jeff Walden a écrit :

On 07/12/2013 04:59 PM, Andrea Giammarchi wrote:

one more thing ... I believe this will impact arrow function too since is 
basically bound callbacks all over the place (or at least this is how I believe 
it will be transpiled)

Sadly, based on the arrow-function patches I've reviewed in SpiderMonkey, I 
don't believe this will be necessarily true.  Arrow functions and bind-bound 
functions are two rather different beasts.  Bind-bound functions are 
potentially constructible; arrow functions never are.  |arguments.callee| 
inside a function that's been bound doesn't refer to the bound function -- it 
refers to the lexical entity.
One of these things I didn't know (and didn't want to know) about the 
language...



(That is, |function f() { return arguments.callee; } f.bind(null)()| is |f|, 
not |b|.)   |arguments.callee| inside an arrow function -- at least, so long as 
arrow functions aren't automatically strict, which decision I would revisit -- 
refers to the arrow function.
arguments.callee is poisoned is strict mode, so the difference you're 
referring only affects non-strict. Should we care? I know I don't.
In general, it should be expected from developers to be in strict mode. 
They also shouldn't be using the arguments object...


which decision I would revisit
= I disagree. Implicit strictness at the function level would surprise 
people a lot. Maybe break their code when turning a function expression 
to an arrow function.
Implicit strictness at the module or class level will already surprise 
people a lot.



I expect there are other differences I'm not yet aware of, that would affect 
having a common implementation of the two concepts.
Even in strict mode? If there are no differences in strict mode, I don't 
think we should care.



It seems like a pretty bad idea to me for arrow functions to not be 
substantially semantically similar to bind-bound functions, but they are as it 
stands now.  I wish I had the time to sit down and think through a solid 
unification of the two concepts.

Hopefully by simplifying how bound functions work?

David
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Why is .bind so slow?

2013-07-13 Thread Allen Wirfs-Brock

On Jul 13, 2013, at 12:39 PM, Mark S. Miller wrote:

 Arrow functions, whether strict or non-strict, are not supposed to have their 
 own |arguments|

Correct.  Implementors should be aware that in the current ES6 draft this is 
stated in a margin note but not in the actual algorithm for function 
declaration instantiations (10.5.3) step 11.


Allen
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Why is .bind so slow?

2013-07-13 Thread Jeff Walden
On 07/13/2013 12:56 PM, Allen Wirfs-Brock wrote:
 On Jul 13, 2013, at 12:39 PM, Mark S. Miller wrote:
 Arrow functions, whether strict or non-strict, are not supposed to have 
 their own |arguments|
 
 Correct.  Implementors should be aware that in the current ES6 draft this is 
 stated in a margin note but not in the actual algorithm for function 
 declaration instantiations (10.5.3) step 11.

Good to know, thanks.  Lack of arguments is sane; last I'd seen in bug 
commentary was that this wasn't the case.

Jeff
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Why is .bind so slow?

2013-07-13 Thread K. Gadd
Sorry Jeff, but this is actually not the case. The performance consequences
from using .bind() can be quite severe because it pollutes type information
and disables fast paths. Not 'your entire application runs in the
interpreter' slow, but surprisingly slow. It can even slow down code paths
where .bind()/bound functions are not being used because of how inline
caches and such tend to work in modern engines.

The problem here isn't that 'calling a bound function is slow'; it's a more
general problem that the introduction of bound functions into an existing
application can make the application get slower in places where the bound
functions aren't being used.

I do agree with the general principle that it is not likely to be the
biggest performance problem, but it's surprisingly harmful. On a related
note, it would certainly be unwelcome if arrow functions had the same
downsides.

-kg

On Sat, Jul 13, 2013 at 12:15 PM, Jeff Walden jwalden...@mit.edu wrote:

 On 07/12/2013 02:54 PM, Allen Wirfs-Brock wrote:
  Looking at it another way, if implementation haven't found it
 straightforward to optimize ES5 bound functions why would you expect that
 would have an easier time with Proxys?

 I'm pretty sure no implementation has seriously tried to optimize bound
 functions, and that that's the major reason for any slowness.  I don't
 think there's anything fundamentally difficult about optimizing bound
 functions.  It's just never been a priority for engines, because it doesn't
 show up in benchmarks and because the perf bugs for it are less pressing
 than other perf work is, as bound functions remain underused on the web.
  Chicken and egg?  Sure.

 In the meantime, while I wouldn't currently question (as a purely
 pragmatic choice) avoiding bind in highly intensive code where every bit of
 perf matters, I do think bound functions are fast enough for the vast
 majority of cases.  The overhead of calling a bound function will rarely be
 the difference between adequate and inadequate performance.

 Jeff

___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Why is .bind so slow?

2013-07-13 Thread Andrea Giammarchi
this makes more sense than `callee` since `.bind()` functions are slow even
in `use strict` scenarios.

However, I was not aware about the fact arrow functions have no arguments
access at all ... between cool and limiting if you ask me but if
performances are better then it's OK.

Also OK would be to have a way to flag a function or a bound one static
so that no `arguments` or `caller` will ever be available 'cause if this is
the performance problem developers would love to have a better way to
improve there.

In the DOM world, as example, all bound functions accepts one single
argument, the event object, while in node.js world basically all emitted
functions accept 2 arguments and never/rarely more than two.

As somebody said already in another thread, me, as developer, would love to
help the JS engine to go faster where needed!

Regards




On Sat, Jul 13, 2013 at 12:39 PM, Mark S. Miller erig...@google.com wrote:

 Arrow functions, whether strict or non-strict, are not supposed to have
 their own |arguments|


 On Sat, Jul 13, 2013 at 11:55 AM, Jeff Walden jwalden...@mit.edu wrote:

 On 07/12/2013 04:59 PM, Andrea Giammarchi wrote:
  one more thing ... I believe this will impact arrow function too since
 is basically bound callbacks all over the place (or at least this is how I
 believe it will be transpiled)

 Sadly, based on the arrow-function patches I've reviewed in SpiderMonkey,
 I don't believe this will be necessarily true.  Arrow functions and
 bind-bound functions are two rather different beasts.  Bind-bound functions
 are potentially constructible; arrow functions never are.
  |arguments.callee| inside a function that's been bound doesn't refer to
 the bound function -- it refers to the lexical entity.  (That is, |function
 f() { return arguments.callee; } f.bind(null)()| is |f|, not |b|.)
 |arguments.callee| inside an arrow function -- at least, so long as arrow
 functions aren't automatically strict, which decision I would revisit --
 refers to the arrow function.  I expect there are other differences I'm not
 yet aware of, that would affect having a common implementation of the two
 concepts.

 It seems like a pretty bad idea to me for arrow functions to not be
 substantially semantically similar to bind-bound functions, but they are as
 it stands now.  I wish I had the time to sit down and think through a solid
 unification of the two concepts.

 Jeff
 ___
 es-discuss mailing list
 es-discuss@mozilla.org
 https://mail.mozilla.org/listinfo/es-discuss




 --
 Cheers,
 --MarkM

___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Why is .bind so slow?

2013-07-13 Thread Andrea Giammarchi
not a part, I am imaging already a scenario where everyone will start
avoiding `.bind()` in order to use arrow functions because these are faster
... something like:

```javascript
obj.method = function () {
  return (e) = {
// rest here
  };
};
node.addEventListener('evt', obj.method());
```

... I don't really like the approach ... can anyone think about a way to
have arrowified functions at definition time? Will classes allow arrow
functions magic inline ? nothing to bind anymore in this case ... different
from the JS I know but that might work pretty well for performance ...
although the prototype would be even more messed up ...





On Sat, Jul 13, 2013 at 9:47 PM, Andrea Giammarchi 
andrea.giammar...@gmail.com wrote:

 this makes more sense than `callee` since `.bind()` functions are slow
 even in `use strict` scenarios.

 However, I was not aware about the fact arrow functions have no arguments
 access at all ... between cool and limiting if you ask me but if
 performances are better then it's OK.

 Also OK would be to have a way to flag a function or a bound one static
 so that no `arguments` or `caller` will ever be available 'cause if this is
 the performance problem developers would love to have a better way to
 improve there.

 In the DOM world, as example, all bound functions accepts one single
 argument, the event object, while in node.js world basically all emitted
 functions accept 2 arguments and never/rarely more than two.

 As somebody said already in another thread, me, as developer, would love
 to help the JS engine to go faster where needed!

 Regards




 On Sat, Jul 13, 2013 at 12:39 PM, Mark S. Miller erig...@google.comwrote:

 Arrow functions, whether strict or non-strict, are not supposed to have
 their own |arguments|


 On Sat, Jul 13, 2013 at 11:55 AM, Jeff Walden jwalden...@mit.edu wrote:

 On 07/12/2013 04:59 PM, Andrea Giammarchi wrote:
  one more thing ... I believe this will impact arrow function too since
 is basically bound callbacks all over the place (or at least this is how I
 believe it will be transpiled)

 Sadly, based on the arrow-function patches I've reviewed in
 SpiderMonkey, I don't believe this will be necessarily true.  Arrow
 functions and bind-bound functions are two rather different beasts.
  Bind-bound functions are potentially constructible; arrow functions never
 are.  |arguments.callee| inside a function that's been bound doesn't refer
 to the bound function -- it refers to the lexical entity.  (That is,
 |function f() { return arguments.callee; } f.bind(null)()| is |f|, not
 |b|.)   |arguments.callee| inside an arrow function -- at least, so long as
 arrow functions aren't automatically strict, which decision I would revisit
 -- refers to the arrow function.  I expect there are other differences I'm
 not yet aware of, that would affect having a common implementation of the
 two concepts.

 It seems like a pretty bad idea to me for arrow functions to not be
 substantially semantically similar to bind-bound functions, but they are as
 it stands now.  I wish I had the time to sit down and think through a solid
 unification of the two concepts.

 Jeff
 ___
 es-discuss mailing list
 es-discuss@mozilla.org
 https://mail.mozilla.org/listinfo/es-discuss




 --
 Cheers,
 --MarkM



___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Why is .bind so slow?

2013-07-12 Thread Claus Reinke

The TypeScript project tries to emulate arrow functions through the
_this = this pattern and keeps running into corner cases where a
semi-naïve renaming is not sufficient.

I have been trying to suggest using .bind to emulate arrow functions
instead, but the counter-arguments are (a) .bind might not be available
(supporting pre-ES5 targets) and (b) .bind is slow.

The polyfill isn't the problem, but I'm a bit shocked every time
someone reminds me of the performance hit for using .bind. Given
that a bound function has strictly more info than an unbound one,
I wouldn't expect that (I expected a bound function to be roughly
the same as an unbound function that does not use this). Unless
there is no special casing for the just-add-this case, and .bind is
always treated as a non-standard (meta-level) call.

While playing with test-code, I also found that v8 does a lot better
than other engines when using an .apply-based .bind emulation.

Can anyone explain what is going on with .bind, .apply and the
performance hits?

The TypeScript issue is https://typescript.codeplex.com/workitem/1322 .
My test code (*) is attached there as bind-for-arrows.html.

Claus
http://clausreinke.github.com/

(*) I also tried to make a jsperf test case, but the way jsperf
   runs the loop seems to prevent the optimization that makes
   v8 look good for the .apply-based bind.


___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Why is .bind so slow?

2013-07-12 Thread Allen Wirfs-Brock
you might consider ticketing performance bugs against the various 
implementations.

Allen


On Jul 10, 2013, at 9:16 AM, Claus Reinke wrote:

 The TypeScript project tries to emulate arrow functions through the
 _this = this pattern and keeps running into corner cases where a
 semi-naïve renaming is not sufficient.
 
 I have been trying to suggest using .bind to emulate arrow functions
 instead, but the counter-arguments are (a) .bind might not be available
 (supporting pre-ES5 targets) and (b) .bind is slow.
 
 The polyfill isn't the problem, but I'm a bit shocked every time
 someone reminds me of the performance hit for using .bind. Given
 that a bound function has strictly more info than an unbound one,
 I wouldn't expect that (I expected a bound function to be roughly
 the same as an unbound function that does not use this). Unless
 there is no special casing for the just-add-this case, and .bind is
 always treated as a non-standard (meta-level) call.
 
 While playing with test-code, I also found that v8 does a lot better
 than other engines when using an .apply-based .bind emulation.
 
 Can anyone explain what is going on with .bind, .apply and the
 performance hits?
 
 The TypeScript issue is https://typescript.codeplex.com/workitem/1322 .
 My test code (*) is attached there as bind-for-arrows.html.
 
 Claus
 http://clausreinke.github.com/
 
 (*) I also tried to make a jsperf test case, but the way jsperf
   runs the loop seems to prevent the optimization that makes
   v8 look good for the .apply-based bind.
 
 ___
 es-discuss mailing list
 es-discuss@mozilla.org
 https://mail.mozilla.org/listinfo/es-discuss
 

___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Why is .bind so slow?

2013-07-12 Thread Andrea Giammarchi
I think we all know that's extremely slow and since ever.
I always wondered the reason too ... in jsperf there are tons of tests
about this, here yet another one just quickly created to compare the gap:
http://jsperf.com/bind-is-slow

in Chrome, bind(context) without even arguments is 87% slower than a
closure with call


On Fri, Jul 12, 2013 at 10:09 AM, Mark S. Miller erig...@google.com wrote:

 If you can manage it, most effective would be to get .bind (or any other
 operation you want to be faster) into some widely quoted benchmark suite.


 On Fri, Jul 12, 2013 at 9:46 AM, Allen Wirfs-Brock 
 al...@wirfs-brock.comwrote:

 you might consider ticketing performance bugs against the various
 implementations.

 Allen


 On Jul 10, 2013, at 9:16 AM, Claus Reinke wrote:

  The TypeScript project tries to emulate arrow functions through the
  _this = this pattern and keeps running into corner cases where a
  semi-naïve renaming is not sufficient.
 
  I have been trying to suggest using .bind to emulate arrow functions
  instead, but the counter-arguments are (a) .bind might not be available
  (supporting pre-ES5 targets) and (b) .bind is slow.
 
  The polyfill isn't the problem, but I'm a bit shocked every time
  someone reminds me of the performance hit for using .bind. Given
  that a bound function has strictly more info than an unbound one,
  I wouldn't expect that (I expected a bound function to be roughly
  the same as an unbound function that does not use this). Unless
  there is no special casing for the just-add-this case, and .bind is
  always treated as a non-standard (meta-level) call.
 
  While playing with test-code, I also found that v8 does a lot better
  than other engines when using an .apply-based .bind emulation.
 
  Can anyone explain what is going on with .bind, .apply and the
  performance hits?
 
  The TypeScript issue is https://typescript.codeplex.com/workitem/1322 .
  My test code (*) is attached there as bind-for-arrows.html.
 
  Claus
  http://clausreinke.github.com/
 
  (*) I also tried to make a jsperf test case, but the way jsperf
runs the loop seems to prevent the optimization that makes
v8 look good for the .apply-based bind.
 
  ___
  es-discuss mailing list
  es-discuss@mozilla.org
  https://mail.mozilla.org/listinfo/es-discuss
 

 ___
 es-discuss mailing list
 es-discuss@mozilla.org
 https://mail.mozilla.org/listinfo/es-discuss




 --
 Cheers,
 --MarkM

 ___
 es-discuss mailing list
 es-discuss@mozilla.org
 https://mail.mozilla.org/listinfo/es-discuss


___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Why is .bind so slow?

2013-07-12 Thread Filip Pizlo

 On Jul 12, 2013, at 10:09 AM, Mark S. Miller erig...@google.com wrote:
 
 If you can manage it, most effective would be to get .bind (or any other 
 operation you want to be faster) into some widely quoted benchmark suite.

In WebKit at least, we have a thing called JSRegress which is meant to be a 
dumping ground for benchmarks for interesting corners of the language. 
Microbenchmarks are welcome; the goal is to just expand coverage of things that 
we measure timings of. It's not widely quoted, and it doesn't get the same 
priority as macrobenchmark suites, but we do care about it and we do optimize 
for it. For example, all of our optimization a for typeof, switch, and 'in' 
arose from JSRegress tests, since none of those things were hot enough in any 
of the major benchmarks. 

We don't have coverage for bind, and it would be great to fix that. 

If you have a standalone program that uses bind, you can either post a patch on 
bugs.webkit.org that adds it to JSRegress (I.e. 
LayoutTests/fast/js/regress/script-tests), or if you're lazy, you can just 
email the program to me and I can do the footwork. The less micro-benchmarky 
the better, but we'll take what we can get. If you have multiple such 
benchmarks for bind then that's even better still. 

TL;DR getting a benchmark to have visibility among implementors is as easy as 
telling them about it. 

-Filip

 
 
 On Fri, Jul 12, 2013 at 9:46 AM, Allen Wirfs-Brock al...@wirfs-brock.com 
 wrote:
 you might consider ticketing performance bugs against the various 
 implementations.
 
 Allen
 
 
 On Jul 10, 2013, at 9:16 AM, Claus Reinke wrote:
 
  The TypeScript project tries to emulate arrow functions through the
  _this = this pattern and keeps running into corner cases where a
  semi-naïve renaming is not sufficient.
 
  I have been trying to suggest using .bind to emulate arrow functions
  instead, but the counter-arguments are (a) .bind might not be available
  (supporting pre-ES5 targets) and (b) .bind is slow.
 
  The polyfill isn't the problem, but I'm a bit shocked every time
  someone reminds me of the performance hit for using .bind. Given
  that a bound function has strictly more info than an unbound one,
  I wouldn't expect that (I expected a bound function to be roughly
  the same as an unbound function that does not use this). Unless
  there is no special casing for the just-add-this case, and .bind is
  always treated as a non-standard (meta-level) call.
 
  While playing with test-code, I also found that v8 does a lot better
  than other engines when using an .apply-based .bind emulation.
 
  Can anyone explain what is going on with .bind, .apply and the
  performance hits?
 
  The TypeScript issue is https://typescript.codeplex.com/workitem/1322 .
  My test code (*) is attached there as bind-for-arrows.html.
 
  Claus
  http://clausreinke.github.com/
 
  (*) I also tried to make a jsperf test case, but the way jsperf
runs the loop seems to prevent the optimization that makes
v8 look good for the .apply-based bind.
 
  ___
  es-discuss mailing list
  es-discuss@mozilla.org
  https://mail.mozilla.org/listinfo/es-discuss
 
 
 ___
 es-discuss mailing list
 es-discuss@mozilla.org
 https://mail.mozilla.org/listinfo/es-discuss
 
 
 
 -- 
 Cheers,
 --MarkM
 ___
 es-discuss mailing list
 es-discuss@mozilla.org
 https://mail.mozilla.org/listinfo/es-discuss
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Why is .bind so slow?

2013-07-12 Thread Oliver Hunt
Just to clarify, JSRegress is not a benchmark in the sunspider/kraken/etc 
sense, as the tests tend far more towards microbenchmarks than full real 
programme tests.  As the name suggests its main purpose is to help us make sure 
we're not regressing core language primitives.

--Oliver

On Jul 12, 2013, at 10:49 AM, Filip Pizlo fpi...@apple.com wrote:

 
 On Jul 12, 2013, at 10:09 AM, Mark S. Miller erig...@google.com wrote:
 
 If you can manage it, most effective would be to get .bind (or any other 
 operation you want to be faster) into some widely quoted benchmark suite.
 
 In WebKit at least, we have a thing called JSRegress which is meant to be a 
 dumping ground for benchmarks for interesting corners of the language. 
 Microbenchmarks are welcome; the goal is to just expand coverage of things 
 that we measure timings of. It's not widely quoted, and it doesn't get the 
 same priority as macrobenchmark suites, but we do care about it and we do 
 optimize for it. For example, all of our optimization a for typeof, switch, 
 and 'in' arose from JSRegress tests, since none of those things were hot 
 enough in any of the major benchmarks. 
 
 We don't have coverage for bind, and it would be great to fix that. 
 
 If you have a standalone program that uses bind, you can either post a patch 
 on bugs.webkit.org that adds it to JSRegress (I.e. 
 LayoutTests/fast/js/regress/script-tests), or if you're lazy, you can just 
 email the program to me and I can do the footwork. The less micro-benchmarky 
 the better, but we'll take what we can get. If you have multiple such 
 benchmarks for bind then that's even better still. 
 
 TL;DR getting a benchmark to have visibility among implementors is as easy as 
 telling them about it. 
 
 -Filip
 
 
 
 On Fri, Jul 12, 2013 at 9:46 AM, Allen Wirfs-Brock al...@wirfs-brock.com 
 wrote:
 you might consider ticketing performance bugs against the various 
 implementations.
 
 Allen
 
 
 On Jul 10, 2013, at 9:16 AM, Claus Reinke wrote:
 
  The TypeScript project tries to emulate arrow functions through the
  _this = this pattern and keeps running into corner cases where a
  semi-naïve renaming is not sufficient.
 
  I have been trying to suggest using .bind to emulate arrow functions
  instead, but the counter-arguments are (a) .bind might not be available
  (supporting pre-ES5 targets) and (b) .bind is slow.
 
  The polyfill isn't the problem, but I'm a bit shocked every time
  someone reminds me of the performance hit for using .bind. Given
  that a bound function has strictly more info than an unbound one,
  I wouldn't expect that (I expected a bound function to be roughly
  the same as an unbound function that does not use this). Unless
  there is no special casing for the just-add-this case, and .bind is
  always treated as a non-standard (meta-level) call.
 
  While playing with test-code, I also found that v8 does a lot better
  than other engines when using an .apply-based .bind emulation.
 
  Can anyone explain what is going on with .bind, .apply and the
  performance hits?
 
  The TypeScript issue is https://typescript.codeplex.com/workitem/1322 .
  My test code (*) is attached there as bind-for-arrows.html.
 
  Claus
  http://clausreinke.github.com/
 
  (*) I also tried to make a jsperf test case, but the way jsperf
runs the loop seems to prevent the optimization that makes
v8 look good for the .apply-based bind.
 
  ___
  es-discuss mailing list
  es-discuss@mozilla.org
  https://mail.mozilla.org/listinfo/es-discuss
 
 
 ___
 es-discuss mailing list
 es-discuss@mozilla.org
 https://mail.mozilla.org/listinfo/es-discuss
 
 
 
 -- 
 Cheers,
 --MarkM
 ___
 es-discuss mailing list
 es-discuss@mozilla.org
 https://mail.mozilla.org/listinfo/es-discuss
 ___
 es-discuss mailing list
 es-discuss@mozilla.org
 https://mail.mozilla.org/listinfo/es-discuss

___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Why is .bind so slow?

2013-07-12 Thread Brendan Eich

Allen Wirfs-Brock wrote:

you might consider ticketing performance bugs against the various 
implementations.


Right, and at most summarize with links to those issues for es-discuss. 
This is not a language issue, rather a quality of implementation one.


/be


Allen


On Jul 10, 2013, at 9:16 AM, Claus Reinke wrote:


The TypeScript project tries to emulate arrow functions through the
_this = this pattern and keeps running into corner cases where a
semi-naïve renaming is not sufficient.

I have been trying to suggest using .bind to emulate arrow functions
instead, but the counter-arguments are (a) .bind might not be available
(supporting pre-ES5 targets) and (b) .bind is slow.

The polyfill isn't the problem, but I'm a bit shocked every time
someone reminds me of the performance hit for using .bind. Given
that a bound function has strictly more info than an unbound one,
I wouldn't expect that (I expected a bound function to be roughly
the same as an unbound function that does not use this). Unless
there is no special casing for the just-add-this case, and .bind is
always treated as a non-standard (meta-level) call.

While playing with test-code, I also found that v8 does a lot better
than other engines when using an .apply-based .bind emulation.

Can anyone explain what is going on with .bind, .apply and the
performance hits?

The TypeScript issue is https://typescript.codeplex.com/workitem/1322 .
My test code (*) is attached there as bind-for-arrows.html.

Claus
http://clausreinke.github.com/

(*) I also tried to make a jsperf test case, but the way jsperf
   runs the loop seems to prevent the optimization that makes
   v8 look good for the .apply-based bind.

___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss



___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Why is .bind so slow?

2013-07-12 Thread K. Gadd
I've had some back and forth with v8 devs about this since it affects my
compiler. I believe they already have open issues about it but I don't know
the bug #s.

In general, the problem seems to be that Function.bind creates functions
that have different type information from normal functions you wrote in
pure JS; they're 'special' native functions in the same fashion as say, a
DOM API:

document.createElement
function createElement() { [native code] }
 function f () {}
f
function f() {}
 f.bind(null)
function () { [native code] }

This is important because v8 tries to gather information about callees at
various call sites. Having a mix of these special and non-special functions
means that the JIT is not able to make safe optimizations based on all the
callers being the same type.

IIRC there are also some other problems specific to v8, like it only being
able to optimize Function.apply and Function.call if the .apply/.call
methods are the implementations used for pure-JS functions (so bind breaks
those too).

I can't comment on why it's slow in SpiderMonkey (I've never asked... I
should file a bug) but it is indeed the case that f.bind(null) produces a
'native code' function in SpiderMonkey, so I expect some of the same
optimization consequences apply.

I also expect that it is much harder for v8 and spidermonkey to inline a
function that contains native code, if not entirely impossible.

All of these problems, as I understand them, are completely fixable. It
might be as simple as making bind return a pure-JS function instead of a
native function. This is supported by the fact that a pure-JS polyfill for
.bind is usually faster in my tests. In general VM authors are much more
helpful when shown real world applications affected by these issues, based
on my experience. They tend to ignore jsperf microbenchmarks, etc.

I don't know that this could be addressed at all from a specification
perspective. The only thing I can think of would be specifying that the
result of Function.bind should somehow be indistinguishable from a
hand-written JS function (no 'native code' in tostring, etc) but I don't
think that sort of spec requirement would actually prevent any of these
performance traps.

Hope this helps,
-kg

On Fri, Jul 12, 2013 at 10:59 AM, Brendan Eich bren...@mozilla.com wrote:

 Allen Wirfs-Brock wrote:

 you might consider ticketing performance bugs against the various
 implementations.


 Right, and at most summarize with links to those issues for es-discuss.
 This is not a language issue, rather a quality of implementation one.

 /be


 Allen


 On Jul 10, 2013, at 9:16 AM, Claus Reinke wrote:

  The TypeScript project tries to emulate arrow functions through the
 _this = this pattern and keeps running into corner cases where a
 semi-naïve renaming is not sufficient.

 I have been trying to suggest using .bind to emulate arrow functions
 instead, but the counter-arguments are (a) .bind might not be available
 (supporting pre-ES5 targets) and (b) .bind is slow.

 The polyfill isn't the problem, but I'm a bit shocked every time
 someone reminds me of the performance hit for using .bind. Given
 that a bound function has strictly more info than an unbound one,
 I wouldn't expect that (I expected a bound function to be roughly
 the same as an unbound function that does not use this). Unless
 there is no special casing for the just-add-this case, and .bind is
 always treated as a non-standard (meta-level) call.

 While playing with test-code, I also found that v8 does a lot better
 than other engines when using an .apply-based .bind emulation.

 Can anyone explain what is going on with .bind, .apply and the
 performance hits?

 The TypeScript issue is 
 https://typescript.codeplex.**com/workitem/1322https://typescript.codeplex.com/workitem/1322.
 My test code (*) is attached there as bind-for-arrows.html.

 Claus
 http://clausreinke.github.com/

 (*) I also tried to make a jsperf test case, but the way jsperf
runs the loop seems to prevent the optimization that makes
v8 look good for the .apply-based bind.

 __**_
 es-discuss mailing list
 es-discuss@mozilla.org
 https://mail.mozilla.org/**listinfo/es-discusshttps://mail.mozilla.org/listinfo/es-discuss


 __**_
 es-discuss mailing list
 es-discuss@mozilla.org
 https://mail.mozilla.org/**listinfo/es-discusshttps://mail.mozilla.org/listinfo/es-discuss

  __**_
 es-discuss mailing list
 es-discuss@mozilla.org
 https://mail.mozilla.org/**listinfo/es-discusshttps://mail.mozilla.org/listinfo/es-discuss

___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Why is .bind so slow?

2013-07-12 Thread Matthew Robb
In the future wouldn't using a Function Proxy be potentially much faster?


On Fri, Jul 12, 2013 at 1:12 PM, K. Gadd k...@luminance.org wrote:

 I've had some back and forth with v8 devs about this since it affects my
 compiler. I believe they already have open issues about it but I don't know
 the bug #s.

 In general, the problem seems to be that Function.bind creates functions
 that have different type information from normal functions you wrote in
 pure JS; they're 'special' native functions in the same fashion as say, a
 DOM API:

 document.createElement
 function createElement() { [native code] }
  function f () {}
 f
 function f() {}
  f.bind(null)
 function () { [native code] }

 This is important because v8 tries to gather information about callees at
 various call sites. Having a mix of these special and non-special functions
 means that the JIT is not able to make safe optimizations based on all the
 callers being the same type.

 IIRC there are also some other problems specific to v8, like it only being
 able to optimize Function.apply and Function.call if the .apply/.call
 methods are the implementations used for pure-JS functions (so bind breaks
 those too).

 I can't comment on why it's slow in SpiderMonkey (I've never asked... I
 should file a bug) but it is indeed the case that f.bind(null) produces a
 'native code' function in SpiderMonkey, so I expect some of the same
 optimization consequences apply.

 I also expect that it is much harder for v8 and spidermonkey to inline a
 function that contains native code, if not entirely impossible.

 All of these problems, as I understand them, are completely fixable. It
 might be as simple as making bind return a pure-JS function instead of a
 native function. This is supported by the fact that a pure-JS polyfill for
 .bind is usually faster in my tests. In general VM authors are much more
 helpful when shown real world applications affected by these issues, based
 on my experience. They tend to ignore jsperf microbenchmarks, etc.

 I don't know that this could be addressed at all from a specification
 perspective. The only thing I can think of would be specifying that the
 result of Function.bind should somehow be indistinguishable from a
 hand-written JS function (no 'native code' in tostring, etc) but I don't
 think that sort of spec requirement would actually prevent any of these
 performance traps.

 Hope this helps,
 -kg

 On Fri, Jul 12, 2013 at 10:59 AM, Brendan Eich bren...@mozilla.comwrote:

 Allen Wirfs-Brock wrote:

 you might consider ticketing performance bugs against the various
 implementations.


 Right, and at most summarize with links to those issues for es-discuss.
 This is not a language issue, rather a quality of implementation one.

 /be


 Allen


 On Jul 10, 2013, at 9:16 AM, Claus Reinke wrote:

  The TypeScript project tries to emulate arrow functions through the
 _this = this pattern and keeps running into corner cases where a
 semi-naïve renaming is not sufficient.

 I have been trying to suggest using .bind to emulate arrow functions
 instead, but the counter-arguments are (a) .bind might not be available
 (supporting pre-ES5 targets) and (b) .bind is slow.

 The polyfill isn't the problem, but I'm a bit shocked every time
 someone reminds me of the performance hit for using .bind. Given
 that a bound function has strictly more info than an unbound one,
 I wouldn't expect that (I expected a bound function to be roughly
 the same as an unbound function that does not use this). Unless
 there is no special casing for the just-add-this case, and .bind is
 always treated as a non-standard (meta-level) call.

 While playing with test-code, I also found that v8 does a lot better
 than other engines when using an .apply-based .bind emulation.

 Can anyone explain what is going on with .bind, .apply and the
 performance hits?

 The TypeScript issue is 
 https://typescript.codeplex.**com/workitem/1322https://typescript.codeplex.com/workitem/1322.
 My test code (*) is attached there as bind-for-arrows.html.

 Claus
 http://clausreinke.github.com/

 (*) I also tried to make a jsperf test case, but the way jsperf
runs the loop seems to prevent the optimization that makes
v8 look good for the .apply-based bind.

 __**_
 es-discuss mailing list
 es-discuss@mozilla.org
 https://mail.mozilla.org/**listinfo/es-discusshttps://mail.mozilla.org/listinfo/es-discuss


 __**_
 es-discuss mailing list
 es-discuss@mozilla.org
 https://mail.mozilla.org/**listinfo/es-discusshttps://mail.mozilla.org/listinfo/es-discuss

  __**_
 es-discuss mailing list
 es-discuss@mozilla.org
 https://mail.mozilla.org/**listinfo/es-discusshttps://mail.mozilla.org/listinfo/es-discuss



 ___
 es-discuss mailing list
 es-discuss@mozilla.org
 

Re: Why is .bind so slow?

2013-07-12 Thread Claus Reinke
Thanks, kg! Your message represents the kind of discussion/information 
I was hoping for. If your hunch as to the reason is correct, it would seem
an easy target for optimization. Partially and efficiently emulating arrow 
functions in ES6 transpilers should be a strong argument in favor, though

not the only one (eg bind keeps coming up as a recommendation when
using class methods as callback parameters, etc.).

For those interested, I've put my (micro) bench in a gist:

   https://gist.github.com/clausreinke/5987876

   (note in particular the performance difference between
   .bind and an .apply-based polyfill; other engines do worse)

I used es-discuss for this thread because:

- all engines are slow on .bind, so it is likely a general issue

- all engines are slow on .bind, so recommending .bind as freely as
   I (and several people on this list) used to do does not seem realistic;
   that puts a serious dent in the usability of this part of the spec

- even if that issue may turn out not to be spec-related, this is the only
   list I know of where I can reach all engine developers and es language
   gurus at once. 


   If this kind of es implementation/performance discussion is not
   welcome here, a dedicated cross-engine list for such topics would 
   be nice. Would only work if all engines had developers listening in.


   As long as there isn't enough traffic to warrant a dedicated list, I 
   (as one of the list owners there) welcome such threads on js-tools


   http://groups.google.com/group/js-tools/about

   (on the basis that engines are our most fundamental js tools;-)

Please let me know where to raise such cross-engine threads in future.
Claus


I've had some back and forth with v8 devs about this since it affects my
compiler. I believe they already have open issues about it but I don't know
the bug #s.

In general, the problem seems to be that Function.bind creates functions
that have different type information from normal functions you wrote in
pure JS; they're 'special' native functions in the same fashion as say, a
DOM API:
... 

___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Why is .bind so slow?

2013-07-12 Thread Allen Wirfs-Brock

On Jul 12, 2013, at 1:55 PM, Matthew Robb wrote:

 In the future wouldn't using a Function Proxy be potentially much faster?

It seems highly unlikely that any use of Proxy will be faster than a rough 
equivalent using an ordinary object.

I expect proxies to be much harder for implementations to optimized than 
ordinary objects.

Looking at it another way, if implementation haven't found it straightforward 
to optimize ES5 bound functions why would you expect that would have an easier 
time with Proxys?

Allen


___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Why is .bind so slow?

2013-07-12 Thread Matthew Robb
If a function proxy is just forwarding an operation through an intermediary
(the proxy and it's call trap) to another function it sounds very similar
to a regularly wrapped/bound js function. So what I am saying is if
browsers implemented bind using a proxy instead of the special native
functions it would be theoretically faster.


On Fri, Jul 12, 2013 at 2:54 PM, Allen Wirfs-Brock al...@wirfs-brock.comwrote:


 On Jul 12, 2013, at 1:55 PM, Matthew Robb wrote:

  In the future wouldn't using a Function Proxy be potentially much faster?

 It seems highly unlikely that any use of Proxy will be faster than a rough
 equivalent using an ordinary object.

 I expect proxies to be much harder for implementations to optimized than
 ordinary objects.

 Looking at it another way, if implementation haven't found it
 straightforward to optimize ES5 bound functions why would you expect that
 would have an easier time with Proxys?

 Allen





-- 
- Matthew Robb
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Why is .bind so slow?

2013-07-12 Thread Andrea Giammarchi
just to add some extra info to this discussion, lo-dash does some crazy
thing to optimize at its best bound functions.

`/\bthis\b/.test(Function.prototype.toString.call(callback))` or something
similar to check if the function needs to use call/apply at all, together
with the number of arguments, and some other analysis to optimize all
further calls to the bound function.

While I believe that's a bit extreme, I have to admit performance gain is
huge so maybe some trick used in lo-dash could be used internally too ?
Like different specialized bound version? Most common use case is still a
method bound to the object itself in order to don't loose the context on
some event call.

my 2 cents





On Fri, Jul 12, 2013 at 4:04 PM, Matthew Robb matthewwr...@gmail.comwrote:

 If a function proxy is just forwarding an operation through an
 intermediary (the proxy and it's call trap) to another function it sounds
 very similar to a regularly wrapped/bound js function. So what I am saying
 is if browsers implemented bind using a proxy instead of the special native
 functions it would be theoretically faster.


 On Fri, Jul 12, 2013 at 2:54 PM, Allen Wirfs-Brock 
 al...@wirfs-brock.comwrote:


 On Jul 12, 2013, at 1:55 PM, Matthew Robb wrote:

  In the future wouldn't using a Function Proxy be potentially much
 faster?

 It seems highly unlikely that any use of Proxy will be faster than a
 rough equivalent using an ordinary object.

 I expect proxies to be much harder for implementations to optimized than
 ordinary objects.

 Looking at it another way, if implementation haven't found it
 straightforward to optimize ES5 bound functions why would you expect that
 would have an easier time with Proxys?

 Allen





 --
 - Matthew Robb

 ___
 es-discuss mailing list
 es-discuss@mozilla.org
 https://mail.mozilla.org/listinfo/es-discuss


___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Why is .bind so slow?

2013-07-12 Thread Andrea Giammarchi
one more thing ... I believe this will impact arrow function too since is
basically bound callbacks all over the place (or at least this is how I
believe it will be transpiled)


On Fri, Jul 12, 2013 at 4:57 PM, Andrea Giammarchi 
andrea.giammar...@gmail.com wrote:

 just to add some extra info to this discussion, lo-dash does some crazy
 thing to optimize at its best bound functions.

 `/\bthis\b/.test(Function.prototype.toString.call(callback))` or something
 similar to check if the function needs to use call/apply at all, together
 with the number of arguments, and some other analysis to optimize all
 further calls to the bound function.

 While I believe that's a bit extreme, I have to admit performance gain is
 huge so maybe some trick used in lo-dash could be used internally too ?
 Like different specialized bound version? Most common use case is still a
 method bound to the object itself in order to don't loose the context on
 some event call.

 my 2 cents





 On Fri, Jul 12, 2013 at 4:04 PM, Matthew Robb matthewwr...@gmail.comwrote:

 If a function proxy is just forwarding an operation through an
 intermediary (the proxy and it's call trap) to another function it sounds
 very similar to a regularly wrapped/bound js function. So what I am saying
 is if browsers implemented bind using a proxy instead of the special native
 functions it would be theoretically faster.


 On Fri, Jul 12, 2013 at 2:54 PM, Allen Wirfs-Brock al...@wirfs-brock.com
  wrote:


 On Jul 12, 2013, at 1:55 PM, Matthew Robb wrote:

  In the future wouldn't using a Function Proxy be potentially much
 faster?

 It seems highly unlikely that any use of Proxy will be faster than a
 rough equivalent using an ordinary object.

 I expect proxies to be much harder for implementations to optimized than
 ordinary objects.

 Looking at it another way, if implementation haven't found it
 straightforward to optimize ES5 bound functions why would you expect that
 would have an easier time with Proxys?

 Allen





 --
 - Matthew Robb

 ___
 es-discuss mailing list
 es-discuss@mozilla.org
 https://mail.mozilla.org/listinfo/es-discuss



___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss