--
You received this message because you are subscribed to the Google Groups "nodejs" group.
To post to this group, send email to nod...@googlegroups.com.
To unsubscribe from this group, send email to nodejs+un...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/nodejs?hl=en.
To unsubscribe from this group, send email to nodejs+un...@googlegroups.com.
Can you bench it against this implementation? I'm curious.
function toArray (args) {
var arr = []
arr.push.apply(arr, args)
return arr
}
I suspect that the overhead of Function#apply will be lower if the
list is long, but higher if the list is short. Since you're testing
with 3 elements (which is a pretty representative use-case) the loop
may be better.
--i
> To unsubscribe from this group, send email to nodejs+un...@googlegroups.com.
Usually, a simple web server getting slammed by ab is used as the benchmark.
2010/6/30 tjholowaychuk <tjholo...@gmail.com>:
> To unsubscribe from this group, send email to nodejs+un...@googlegroups.com.
Mine too, and I wrote Array.prototype.slice :-)
One reason could be that the Array.prototype.slice spec requires you
to treat undefined properties in the source array differently from
properties that are present, but contain 'undefined'. If the source
array has lots of uninitialized slots this will slow you down a lot.
Another reason could be a bug in the fast version :-).
> To unsubscribe from this group, send email to nodejs+un...@googlegroups.com.
Put args.length in a local?
> To unsubscribe from this group, send email to nodejs+un...@googlegroups.com.
Any faster if args.length is saved to a var first?
On Jun 30, 2010 3:13 PM, "tjholowaychuk" <tjholo...@gmail.com> wrote:
ah! we have a winner
var arr = new Array(args.length);
for (var i = 0, len = args.length; i < len; ++i) {
arr[i] = args[i];
}
return arr
is 1.5 times faster than my initial implementation, and 16 times
faster than Array.prototype.slice.call
On Jun 30, 12:03 pm, Marco Rogers <marco.rog...@gmail.com> wrote:
> This thread is really abusing m...
var args_length = args.length;
var arr = new Array(args_length);
for (var i = 0, len = args_length; i < len; ++i) {
arr[i] = args[i];
}
return arr;
If anyone is interested in speed of loops in javascript, see:
http://blogs.sun.com/greimer/entry/best_way_to_code_a
Kind regards,
Jan
--
really? forEach() would be slow... cached for loop is nearly the same
as while(n--)
To unsubscribe from this group, send email to nodejs+un...@googlegroups.com.
On Thu, Jul 1, 2010 at 5:36 AM, tjholowaychuk <tjholo...@gmail.com> wrote:really? forEach() would be slow... cached for loop is nearly the same
as while(n--)I think that V8 takes the native forEach 'inside', which benchmarking script are you guys using?
I haven't tested this construct, but I did comparison in
December/January between:
for(var i = 0, ii = arry.length; i < ii; i++){/*...*/}
and
for(var i = arry.length - 1; i >= 0 ; i--){/*...*/}
The first was several times faster, so I assumed it was caught and
fast pathed while the second construct wasn't. Not sure if this is
still true or not.
I think he's saying that the body of the function gets inlined.
Essential forEach gets turned into the equivalent of a for loop.
Don't know if that's true, but that's how I read the statement. But
I'm sure there are time where v8 can't make that optimization.
Depends on the free variables involved and where else the function
passed to forEach is used.
Also have you tried this latest variant with arr.push? It's still
blowing my mind that that was faster than the index assignment. Maybe
that was a strange fluke of the previous implementations and this will
show different results.
> ...
>
> read more »
--
You received this message because you are subscribed to the Google Groups "nodejs" group.
To post to this group, send email to nod...@googlegroups.com.
Nope. You have to remember that the programmer at any time can write
Array.prototype.forEach = function() { // funky stuff }. The inlined
version would then have to be magically out-of-lined for subsequent
calls. We can't do that.
What's happening here is that the loop variable and all the other
variables in the classic case are variables on the global object.
It's not a local variable because you are not inside a function.
Being inside {} doesn't do it.
Global variables are properties of a big hash map (the global object).
We've done a lot to optimize that, but at the end of the day it's
still a lot faster to have a local variable in the function that can
be register allocated. So that slows down the classic version a lot.
The forEach version is being slowed down by having a function call in
the inner loop. Apparently that is even more expensive than having
globals as your variables.
>
> Chrome (5.0.342.9 beta)
> classic: 23370
> forEach : 773
> I am a bit at a loss to explain this discrepancy
This is strange and I can't reproduce it with my version of Chrome 5.
Is the above code the only thing on the page or have you added jQuery
or something? Having a DOM object called 'i' might cause that sort of
slowdown since they are on the global object like the i variable.
var a = new Array(10);
Array.prototype[5] = 42;
a[5]; // Is 42. Checking for this is slow.
I'm not sure why your test is giving a different result.
Here is the entire text of my benchmark:
function using_loop(a) {
for (var i = 0; i < 1000; i++) {
var len = a.length;
var b = new Array(len);
for (var j = 0; j < len; j++) {
b[j] = a[j];
}
}
}
function using_slice(a) {
for (var i = 0; i < 1000; i++) {
var b = a.slice(0);
}
}
function benchmark_with_zeros(fun) {
var a = new Array(100);
for (var i = 0; i < 100; i++) {
a[i] = 0;
}
fun(a);
}
function benchmark_with_holes(fun) {
var a = new Array(100);
fun(a);
}
function benchmark_with_oldspace_objects(fun) {
var a = new Array(100);
for (var i = 0; i < 100; i++) {
a[i] = true;
}
fun(a);
}
function benchmark_with_newspace_objects(fun) {
var a = new Array(100);
for (var i = 0; i < 100; i++) {
a[i] = i + 0.2;
}
fun(a);
}
function variant(name, initializer, do_copy) {
var elapsed = 0;
var start = new Date();
for (var n = 0; elapsed < 2000; n++) {
initializer(do_copy);
elapsed = new Date() - start;
}
print('Time (' + name + '): ' + Math.floor(1000 * elapsed/n) + ' us.');
}
variant("loop-zeros", benchmark_with_zeros, using_loop);
variant("loop-oldspace", benchmark_with_oldspace_objects, using_loop);
variant("loop-newspace", benchmark_with_newspace_objects, using_loop);
variant("loop-holes", benchmark_with_holes, using_loop);
variant("slice-zeros", benchmark_with_zeros, using_slice);
variant("slice-oldspace", benchmark_with_oldspace_objects, using_slice);
variant("slice-newspace", benchmark_with_newspace_objects, using_slice);
variant("slice-holes", benchmark_with_holes, using_slice);
2010/6/30 tjholowaychuk <tjholo...@gmail.com>:
> --
> You received this message because you are subscribed to the Google Groups "nodejs" group.
> To post to this group, send email to nod...@googlegroups.com.
> To unsubscribe from this group, send email to nodejs+un...@googlegroups.com.
In NodeJS, all modules are executed "inside a function", all the time.
--i