最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

performance - JavaScript - Are loops faster than discretely writing line-by-line? - Stack Overflow

programmeradmin3浏览0评论

Ignoring all code cleanliness and readability, which script will finish quicker?

This:

for(var i = 0; i < 10; i++){
  --do that thing--
}

Or this:

--do that thing--
--do that thing--
--do that thing--
--do that thing--
--do that thing--
--do that thing--
--do that thing--
--do that thing--
--do that thing--
--do that thing--

Or are they the same, performance-wise?

Ignoring all code cleanliness and readability, which script will finish quicker?

This:

for(var i = 0; i < 10; i++){
  --do that thing--
}

Or this:

--do that thing--
--do that thing--
--do that thing--
--do that thing--
--do that thing--
--do that thing--
--do that thing--
--do that thing--
--do that thing--
--do that thing--

Or are they the same, performance-wise?

Share Improve this question edited Jul 20, 2017 at 13:32 C8H10N4O2 19k9 gold badges104 silver badges143 bronze badges asked Jun 29, 2016 at 22:55 user3163495user3163495 3,6734 gold badges37 silver badges56 bronze badges 5
  • 1 Or option 3: build up the required html in a variable and only update the DOM once at the end. Why do you ask? Are you having a performance problem with your page, or are you just curious? – nnnnnn Commented Jun 29, 2016 at 22:59
  • can you remove document.write and replace it with e. g. a placeholder to make this question more generic about 'loop unrolling' or similar? Otherwise most people will probably focus on the document.write aspect / downvote. – le_m Commented Jun 29, 2016 at 22:59
  • 1 just directly count = 9; will be quickest (: – num8er Commented Jun 29, 2016 at 23:05
  • @nnnnnn The work the scripts are doing is irrelevant; I updated the question to be more generic. – user3163495 Commented Jun 29, 2016 at 23:05
  • 3 It’s not irrelevant. JS engines will optimize loops like these, they won’t optimize repetitive statements like these. In general: loops are optimized. Use the thing that you would normally use (the loop, built-in methods, etc.), because they have the highest probability of being optimized. – Sebastian Simon Commented Jun 29, 2016 at 23:11
Add a ment  | 

4 Answers 4

Reset to default 12

"Unrolling" a loop by repeatedly "copy & pasting" the loop body can improve or reduce performance.

The oute depends on...

  • ...your JavaScript engine
  • ...the code in the loop body
  • ...how well documented your code is (no kidding!)

Let's analyze the performance using Google's popular V8 JavaScript engine (Chrome, Node):

Ordinary loop:

var count = 0;
for (var i = 0; i < 10; i++) {
  count += 1;
}

Unrolled loop:

var count = 0;
count += 1;
count += 1;
... 
count += 1;

Result: The unrolled loop is about 10x faster.

But what if we loop 1000 times instead of 10 times? Then the unrolled loop suddenly bees more than 10x slower than the ordinary loop!

And what if we swap the simple arithmetic expression with a function call?

Ordinary loop:

function f() {
  return 1;
}

var count = 0;
for (var i = 0; i < 10; i++) {
  count += f();
}

Unrolled loop:

var count = 0;
count += f();
count += f();
... 
count += f();

Result: The unrolled loop is about 50% faster.

But what if we add a ment to our function f?

function f() {
  // bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla
  return 1;
}

Suddenly the unrolled loop is about 20% slower!

Why is that?

  • V8 automatically inlines code when parsing functions whose body contains less than 600 characters, including whitespace and ments.
  • V8 performs on-stack-replacement when a function is 'stuck' in a very long loop.

Regarding the last example: By adding a long > 600 character ment, we prevent V8 from inlining the function f during parsing and rely on the run-time optimization capabilities (such as 'on stack replacement') which target whole functions and loops but not manually repeated code.

As you can see, it is quite hard to predict the oute of such micro-"optimization". So better don't do it - unless you target a specific version of a specific JS engine.

See https://jsfiddle/Lj9v7c2m/ for the performance analysis - you might get different results depending on your puter / browser / version.

One factor this depends on is which JS engine you're using. Loop unrolling is a mon optimization technique that can employed without your intervention, so it really depends on which engine your code is being interpreted by.

Typically you can use http://jsperf./ to test specific code for performance differences in different browsers, but it seems to have been down for several days for maintenance. Instead you can manually place each selection of code in their own functions, store the time at the beginning of the test, call the function 10,000 times or something, then log the time elapsed. Here's an example:

    function testEmpty(){ }
    function testLoop(){
        for(var i = 0; i < 10; i++){void i;}
    } function testUnrolled(){
        void 0;void 1;void 2;void 3;void 4;void 5;void 6;void 7;void 8;void 9;
    }
    function testLoop2(){
        for(var i = 0; i < 10; i++){void Date();}
    } function testUnrolled2(){
        void Date();void Date();void Date();void Date();void Date();
        void Date();void Date();void Date();void Date();void Date();
    }
    function testFunction(func, num){
        var a=Date.now();
        for(var i=0;i<num;i++){
            func();
        }
        return Date.now() - a;
    }
    console.log(testFunction(testEmpty,10000000)); // Took 9ms
    console.log(testFunction(testLoop,10000000)); // Took 112ms
    console.log(testFunction(testUnrolled,10000000)); // Took 42ms
    console.log(testFunction(testLoop2,10000)); // Took 705ms
    console.log(testFunction(testUnrolled2,10000)); // Took 714ms

Keeping the browser constant (Firefox 47), this actually shows that performance changes are not tied to one coding style. As a matter of fact, depending on what is being repeated makes a difference.

Overall, incrementing a loop to 10 will have a pletely unnoticeable performance impact so usually the difference is negligible (and performance probably shouldn't be a consideration for which style to use).

which script will finish quicker

There is no the only valid answer to that.

The other answers speculate with assumptions.

The standard does not guarantee any of those to be faster/slower, so one can only state something for a given ES implementation running on a given machine and only after they measure it. Beware though, that getting any sensible numbers after microbenchmarking is hard (most benchmarks produce some numbers and not necessary those numbers mean anything).

Second version is quicker if it's just simple calculation statement.

But why to do code so ugly and unreadable (it depends on statements per line) when You can just loop it.

In another hand code will be optimized and You will not feel the difference.

Also keep in mind that it's JS. So in some cases statements can be asynchronous that run without sequence (without waiting for ending of previous statement).

Programmer is not code looping machine, programmer must write once and enjoy automatization.

发布评论

评论列表(0)

  1. 暂无评论