Skip to content

Instantly share code, notes, and snippets.

@rep-movsd
Created May 10, 2017 06:32
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save rep-movsd/0db832ed1b12d63098aadfc42c301de1 to your computer and use it in GitHub Desktop.
Save rep-movsd/0db832ed1b12d63098aadfc42c301de1 to your computer and use it in GitHub Desktop.
Why is JS inbuilt forEach slower than a hand rolled forEach?
rep ~ $ node
> a = [];
[]
> for(var i = 0; i < 10000; ++i) a.push(i);
10000
>
>
> function f()
... {
... console.time("f");
... var sum = 0;
... for(var i = 0; i < 100; ++i)
... {
..... a.forEach(function(number) {sum += number;});
..... }
...
... console.timeEnd("f");
... }
undefined
>
>
> function g()
... {
... console.time("g");
... var sum = 0;
... for(var i = 0; i < 100; ++i)
... {
..... for(var j = 0; j < a.length; ++j) sum += a[j];
..... }
...
... console.timeEnd("g");
... }
undefined
>
>
> function mysa_foreach(arr, fn)
... {
... for(var j = 0; j < arr.length; ++j) fn(a[j]);
... }
undefined
>
> function h()
... {
... console.time("h");
... var sum = 0;
... for(var i = 0; i < 100; ++i)
... {
..... mysa_foreach(a, function(number) {sum += number;});
..... }
...
... console.timeEnd("h");
... }
undefined
>
> for(var z = 0; z< 10; ++z) f();
f: 30.872ms
f: 31.891ms
f: 31.601ms
f: 32.743ms
f: 31.794ms
f: 31.921ms
f: 31.595ms
f: 32.382ms
f: 32.158ms
f: 31.636ms
undefined
> for(var z = 0; z< 10; ++z) g();
g: 4.396ms
g: 1.872ms
g: 1.862ms
g: 1.868ms
g: 1.862ms
g: 1.868ms
g: 1.868ms
g: 1.862ms
g: 1.867ms
g: 1.862ms
undefined
> for(var z = 0; z< 10; ++z) h();
h: 21.165ms
h: 22.423ms
h: 21.923ms
h: 21.495ms
h: 19.450ms
h: 18.529ms
h: 19.245ms
h: 19.130ms
h: 19.319ms
h: 18.805ms
undefined
>
>
>
@rep-movsd
Copy link
Author

a = [];
for(var i = 0; i < 10000; ++i) a.push(i);

function f()
{
  console.time("f");
  var sum = 0;
  for(var i = 0; i < 100; ++i)
  {
    a.forEach(function(number) {sum += number;});
  }

  console.timeEnd("f");
}


function g()
{
  console.time("g");
  var sum = 0;
  for(var i = 0; i < 100; ++i)
  {
    for(var j = 0; j < a.length; ++j) sum += a[j];
  }

  console.timeEnd("g");
}


function mysa_foreach(arr, fn)
{
  for(var j = 0; j < arr.length; ++j) fn(a[j]);
}

function h()
{
  console.time("h");
  var sum = 0;
  for(var i = 0; i < 100; ++i)
  {
    mysa_foreach(a, function(number) {sum += number;});
  }
  
  console.timeEnd("h");
}

function k () 
{
  console.time("k")
  for(var i = 0; i < 100; ++i)
  {
    var sum = a.reduce(function(t_sum, next_item) { return t_sum + next_item}, 0);
  }
  console.timeEnd("k")
}


for(var z = 0; z< 10; ++z) f();
for(var z = 0; z< 10; ++z) g();
for(var z = 0; z< 10; ++z) h();
for(var z = 0; z< 10; ++z) k();

@DanBradbury
Copy link

http://www.ecma-international.org/ecma-262/6.0/#sec-array.prototype.foreach

seems like the generic definition might be the problem

Copy link

ghost commented May 10, 2017

Generic functions that take any type and not just one specific type has performance penalties due to the dynamic nature of JS.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment