Re: addEvent - The late entry :)
kangax wrote:
Faster, but not usefully so.
However, it seems that the fastest method of turning an arguments object
into an array is:-
((arguments.len gth == 1)?[arguments[0]]:Array.apply(th is, arguments))
- where - this - is the global object in my tests, but should not be
altered by the process so could be any object. I did try null as first
argument, which is fine on everything but Firefox, where it makes the
process considerably slower than using an object reference.
Unfortunately when the Array constructor, called as a function (so not
with the - new - keyword), is only given one argument and that argument
turns out to be a numeric value that is a positive integer smaller than
2 to the power of 32 then you get different behaviour. So the expression
has to include that special handling for (arguments.leng th == 1). My
test still show that whole expression outperforming all of the
alternatives that I could think of.
The precise benefit depends on the number of arguments. With zero
arguments the different can be very small on some browsers (especially
firefox and IE). I did my comparisons against Prototype.js's - $A -
function , which is considered to be 100% in the following numbers. At
20 arguments Windows Safari 3 executes that expression in 48% of the
time, and at zero arguments 47%. Mac Safari 2 was better, ranging from
16% with 20 arguments down to 34% with zero.
Opera 9.2 showed the next greatest performance change. 23% at 20
arguments and 57% at zero.
IE 7 came next with 62% at 20 arguments and 81% at zero.
IE 6: 65% to 89%.
Firefox 2.0.4 was the worst I have tried to date. At 20 arguments it
only manages 79% and was down to 85% by zero arguments, but the actual
execution time for the expression (and all of the alternatives) was the
longest of the group tested on the same hardware (by at least a factor
of 2) so the actual gain in time saved was still greater than for some
of the better performing JS engines.
Array.prototype .slice.call(arg uments, X); - has still got to be the
fastest method if not all of the arguments are wanted, and (strangely) -
Array.prototype .splice.call(ar guments, 0, arguments.lengt h); - is
another alternative, but there, with Windows Safari 3, the benefit
dropped off with more arguments and at 8 arguments it was worse than -
$A -.
These were tests on a mixture of Pentium 4, Core 2 Duo and Core 2 Quad
processors and Windows and Mac OSs so the results may not yet be
sufficiently reprehensive for the comparisons to hold in general. I will
probably post the test code for these tomorrow (or soonish) in case
anyone wants to see if other hardware permutations contradict those
results (or try it with other browsers/OSs).
Richard.
kangax wrote:
On Jul 21, 5:37 pm, Richard Cornford wrote:
>
>
>
I didn't know about Array.prototype .push being faster than
Array.prototype .concat in this case. Thanks for the tip.
>
>[snip]
>And finally, using the - concat - method to append an array created
>from
>the arguments object is very convoluted and relatively inefficient
>when
>the arguments object can be used as the second argument to the -
>apply -
>method and the - apply - method could be called on - push -, which
>will
>take any number of arguments and append them to an array. That is:-
>__method.apply (object, args.concat($A( arguments))); - can be replaced
>with - __method.apply( obj, args.push.apply (args, arguments)); - and
>should result in superior performance.
>from
>the arguments object is very convoluted and relatively inefficient
>when
>the arguments object can be used as the second argument to the -
>apply -
>method and the - apply - method could be called on - push -, which
>will
>take any number of arguments and append them to an array. That is:-
>__method.apply (object, args.concat($A( arguments))); - can be replaced
>with - __method.apply( obj, args.push.apply (args, arguments)); - and
>should result in superior performance.
I didn't know about Array.prototype .push being faster than
Array.prototype .concat in this case. Thanks for the tip.
However, it seems that the fastest method of turning an arguments object
into an array is:-
((arguments.len gth == 1)?[arguments[0]]:Array.apply(th is, arguments))
- where - this - is the global object in my tests, but should not be
altered by the process so could be any object. I did try null as first
argument, which is fine on everything but Firefox, where it makes the
process considerably slower than using an object reference.
Unfortunately when the Array constructor, called as a function (so not
with the - new - keyword), is only given one argument and that argument
turns out to be a numeric value that is a positive integer smaller than
2 to the power of 32 then you get different behaviour. So the expression
has to include that special handling for (arguments.leng th == 1). My
test still show that whole expression outperforming all of the
alternatives that I could think of.
The precise benefit depends on the number of arguments. With zero
arguments the different can be very small on some browsers (especially
firefox and IE). I did my comparisons against Prototype.js's - $A -
function , which is considered to be 100% in the following numbers. At
20 arguments Windows Safari 3 executes that expression in 48% of the
time, and at zero arguments 47%. Mac Safari 2 was better, ranging from
16% with 20 arguments down to 34% with zero.
Opera 9.2 showed the next greatest performance change. 23% at 20
arguments and 57% at zero.
IE 7 came next with 62% at 20 arguments and 81% at zero.
IE 6: 65% to 89%.
Firefox 2.0.4 was the worst I have tried to date. At 20 arguments it
only manages 79% and was down to 85% by zero arguments, but the actual
execution time for the expression (and all of the alternatives) was the
longest of the group tested on the same hardware (by at least a factor
of 2) so the actual gain in time saved was still greater than for some
of the better performing JS engines.
Array.prototype .slice.call(arg uments, X); - has still got to be the
fastest method if not all of the arguments are wanted, and (strangely) -
Array.prototype .splice.call(ar guments, 0, arguments.lengt h); - is
another alternative, but there, with Windows Safari 3, the benefit
dropped off with more arguments and at 8 arguments it was worse than -
$A -.
These were tests on a mixture of Pentium 4, Core 2 Duo and Core 2 Quad
processors and Windows and Mac OSs so the results may not yet be
sufficiently reprehensive for the comparisons to hold in general. I will
probably post the test code for these tomorrow (or soonish) in case
anyone wants to see if other hardware permutations contradict those
results (or try it with other browsers/OSs).
Richard.
Comment