I'd like to see how we can combine all of this elegantly with bindAsEventListener and curry.
Event if the cost for this is an extra function call. On Mar 14, 4:24 pm, kangax <[email protected]> wrote: > On Mar 14, 9:15 am, Robert Kieffer <[email protected]> wrote: > > > > > On Mar 13, 4:33 pm, Tobie Langel <[email protected]> wrote: > > > > > It's this latter case where having the args array cached provides > > > > significant performance benefit, which I would argue is worth doing, > > > > even if it slightly lessens the performance of "someFunc()" with no > > > > arguments. That's the tradeoff we're talking about. > > > I don't think that tradeoff is necessary, actually. > > > Are you saying you don't think we should make this tradeoff > > (i.e. we should use Kangax's code) or that you believe we can get > > the best of both worlds? > > > If the latter, I'm not sure how you manage that. We're either using > > Kangax's code for the inner-most function or the "Improved" code. (As > > a reminder to readers, both implementations are available at the > > bottom of the source on this > > page:http://www.broofa.com/Tools/JSLitmus/tests/PrototypeBind.html > > ). Here are the relevant snippets: > > > Kangax: > > function() { > > return arguments.length > > ? fn.apply(context, args.concat(_slice.call(arguments))) > > : fn.apply(context, args); > > } > > > Improved: > > function() { > > var ll = arguments.length; > > args.length = l + ll; while (ll--) args[l+ll] = arguments[ll]; > > return fn.apply(context, args); > > }; > > > Where argumens.length is zero, the Improved code has *slightly* more > > overhead. But in the case of arguments > 0, the Improved code reuses > > the args array instead of making the _slice.call(), which appears to > > be more performant in most cases. > > > Ergo, it's a tradeoff of some sort - pick your implementation - and I > > feel the Improved variant provides more desirable performance > > characteristics. It provides the best performance for the slowest case > > ("the weakest link"). So for most projects I think it will provide > > better real-world performance. > > Why not combine two? > > ... > function() { > if (arguments.length) { > var ll = arguments.length; > args.length = l + ll; > while (ll--) { > args[l+ll] = arguments[ll]; > } > } > return fn.apply(context, args);} > > ... > > On a side note, I am pretty sure that *most* of the projects do *not* > do partial application. This means that second branch (the one that > uses your optimization) is rarely entered. > > To make it clearer, let's mark 4 possible outcomes: > > var slice = Array.prototype.slice; > > function bind(context) { > var fn = this; > // "plain" version, no partial application > if (arguments.length == 1) { > return function() { > return arguments.length > // 1 > ? fn.apply(context, arguments) > // 2 > : fn.call(context) > } > } > // partial application > var args = _slice.call(arguments, 1); > return function() { > return arguments.length > // 3 > ? fn.apply(context, args.concat(slice.call(arguments))) > // 4 > : fn.apply(context, args) > } > > } > > When is #1 function used? When there was no partial, but arguments > were passed to bound function: > > function foo(){}; > var bound = foo.bind({}); > bound('blah'); > > When is #2 function used? When there was no partial and arguments were > not passed to bound function: > > function foo(){}; > var bound = foo.bind({}); > bound(); > > When is #3 function used? When there was partial and arguments were > passed to bound function. This is your optimization branch. > > function foo(){}; > var bound = foo.bind({}, 'bar'); > bound('baz'); > > And finally, when is function #4 used? When there was partial and > arguments were not passed to bound function. > > function foo(){}; > var bound = foo.bind({}, 'bar'); > bound(); > > In my opinion, first and second versions are the ones that are used > more often (but I would want to hear other folks). These 2 versions > never use arrays' concatenation (since there are no "partial" > arguments to "concat" with in the first place). > > -- > kangax --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Prototype & script.aculo.us" 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/prototype-scriptaculous?hl=en -~----------~----~----~----~------~----~------~--~---
