1

I decided to assess all of my for loops in my project to see if I could replace it with an Array.prototype method - 75% of them could easily be replaced. Before I started the replacements, I thought I might run some tests. Most prototype methods were significantly slower (~80%) than polyfills on my machine.

Each of these tests are faster with a regular for loop

I did not have the time to look up other jsperf tests, but i'm sure most prototype methods will be slower. So why? These functions are very useful, but how come they are so much slower than simple for loops.

Chrome 60.0.3112 / Windows 10 0.0.0

Thomas Wagenaar
  • 6,489
  • 5
  • 30
  • 73
  • 3
    I'd guess that it's due to the overhead involved in calling a function (new scope/context) for each array item. For me, the native functions are so fast (e.g. 74 million ops/sec for array.some) that users aren't going to see a difference and the time saved not writing/maintaining my own function is worth it. – Joe Aug 11 '17 at 13:25
  • Most of the tests are flawed because they're just doing different things (e.g. `concat` creating a new array vs. `push` adding to an existing one). Also your `find` test is fundamentally broken with its `return` statement outside of a function. – Bergi Aug 11 '17 at 13:46

1 Answers1

0

Unless js is parsed and we never know what the actual executed machine code looks like, its probably a good way of checking the efficiency of a high level algorithm to transpile it to assembly.

1) a regular for loop:

loop:
  CP A,100 //the exit statement
  JP z,end // exit

  LD A,123//some random math
  LD B,124
  ADD A,B
  LD 123,A

  JP loop //the actual loop     

end:

2) a prototype function:

Array_forEach:
loop:
  CP A,B //the exit statement
  JP z,end // exit

  LD 123,A//remove values from direct registers
  LD 124,B

  LD arg1,array_length //prepare function environment
  LD arg2,A

  CALL anonymous_func

  LD A,123
  LD B,124

  JP loop //the actual loop

anonymous_func:
  LD A,123//some random math
  LD B,124
  ADD A,B
  LD 123,A
  RET

As you can see, the forEach uses some expensive CALLs, not to mention the context change.


However, the parser may not even let both run that deep level, or it does some really good inlining, meaning that forEach actually runs faster than a for loop sometimes.

Jonas Wilms
  • 132,000
  • 20
  • 149
  • 151