2

I'm working on a library specifically for Utilities. It will have functions that help you manipulate: Strings, Arrays, Numbers, Objects, and more. Performance is a main focus. While working on the repeat function for Strings (repeat a string n number of times), I decided to test out how fast my current method:

Array(n + 1).join(string); // n = times to repeat; string = string to copy

is compared to just using a loop. It turns out, that while this is the shortest way to repeat a string, it is also the slowest. I do understand it is still fast. I mean, it is impossible for a human to do 200,000 things in 1 second but in comparison to loops it is slow.

What makes loops so fast? One loop I noticed that is particularly fast is the while loop which contain i--:

var i = 10;
while (i--) {
    // do stuff
}

I decided to use this method since it is the fastest. But I wanted to know why? What makes it so much faster than the other methods?

Here is my benchmark. The only browser where the while loop was slower than the for loop was in Opera. It was especially fast in Internet Explorer 10.

Shawn31313
  • 5,978
  • 4
  • 38
  • 80
  • Asking why a "negative while loop" is fast really only makes sense compared to a "positive while loop" or a for loop. What you're asking here is "Why is a loop faster than creating an array and joining its undefined elements with my string?" I know you have the other loop cases in your performance test, but note that your negative for loop is not equivalent, it should be `for (var i=10; i--;)` – nnnnnn Aug 02 '13 at 22:03
  • 1
    your minusWhile is so fast because it never does any work in the loop body and neither does minus do While ... Other than that, you should note that the loops are all basically the same speed. in general, there is no free lunch: anytime you see an outlier like that, debug your test code. if you were going more repeats than 10, i would expect the Array.join method to surpass the loops in performance. – dandavis Aug 02 '13 at 22:08
  • @nnnnnn: are you sure that "var i = 0; while (i--) {" does something ? (i don't think so...) besides, how could doubling or even tripling the work cause a dozens-fold decrease in performance instead of a 2-3 fold decrease? – dandavis Aug 02 '13 at 22:15
  • Good point @dandavis. (Previous comment deleted.) I thought you were referring to the code shown directly in the question that only has a comment in the body. So to spell out your point more clearly: in the jsperf test the minus while loops are initialising `i` to the wrong value. – nnnnnn Aug 02 '13 at 22:17

1 Answers1

0

Your js perf has many faults, you have:

  • Off by one, off by ten, and off by nine errors
  • Code inlined in the test
  • No check for the result

In the fixed jsperf the results make more sense:

enter image description here

Note that += str is optimized and is more like using a StringBuilder. If that was your confusion. The Array code allocates a new array and calls join, which is a complex function with convoluted semantics. .join is also not optimized by V8.

For the rest of the code they are always very close within each other differently on each run so they have same performance.


The duplicate has wrong info too, if you are looping through an array then you are working against the CPU cache, so not only is negative pretty much the same in best case, but also worse if you are looping through an array. It shows up in jsperf too.

Esailija
  • 138,174
  • 23
  • 272
  • 326