-1

Consider this code snippet:

var x = 10;
for (var i=0; i<100; i++) {
    if (x === 10) {
        /* do some stuff */
    }
}

The condition within the if-statement is static except for x, whose value is evaluated only once just before entering the loop. This value could come from anywhere - it can be hard coded, an input from the user, the result of a math problem, etc. The point is that once x is evaluated, it doesn't change. Therefore, the condition inside the if-statement would be the same at every loop iteration, but the code clearly evaluates the condition nonetheless, wasting processing cycles in the process. Is there a way to make the condition evaluate once and have every iteration afterwards immediately execute the right code branch?

Manuel
  • 2,143
  • 5
  • 20
  • 22
  • Keep in mind that modern [branch prediction](https://stackoverflow.com/questions/11227809/why-is-processing-a-sorted-array-faster-than-processing-an-unsorted-array) can help significantly with this sort of thing *automatically* – CertainPerformance Jul 18 '19 at 00:22
  • What if you just swap `if` and `for` then? – zerkms Jul 18 '19 at 00:25
  • Is there more in the loop than the code that depends on the condition? – Barmar Jul 18 '19 at 00:27
  • 1
    Are you really executing this code so much that the overhead of simple comparison is impacting performance? – Barmar Jul 18 '19 at 00:29
  • Don't worry about this unless it's actually causing a performance problem. [Premature optimization is the root of all evil](http://c2.com/cgi/wiki?PrematureOptimization). Most of the time the difference is negligible. Write it in the way that's most clear to the reader, worry about performance later if necessary. – Barmar Jul 18 '19 at 00:29

1 Answers1

4

One option is to save the condition in advance, so that you don't need to re-check x every time:

var x = 10;
var doCondition = x === 10;
for (var i=0; i<100; i++) {
    if (doCondition) {
        /* do some stuff */
    }
}

Another option is to have two separate functions, one for if the condition is fulfilled, and one for when it's not. It'd be WET, but the condition would only be evaluated once. Eg, you could turn

var x = 10;
var doCondition = x === 10;
for (var i=0; i<100; i++) {
    if (doCondition) {
        /* do some stuff */
    } else {
        // do some other stuff
    }
}

into

const fns = {
  trueCond() {
    for (var i=0; i<100; i++) {
      // do some stuff
    }
  },
  falseCond() {
    for (var i=0; i<100; i++) {
      // do some other stuff
    }
  }
  // insert other conditions here, if you want
  // could also just use if/else statements containing loops,
  // rather than an object of functions
};
const fn = x === 10 ? fns.trueCond : fns.falseCond;
fn();

It depends on how complicated the loop is / what other operations are being performed.

Still, this is almost always a case of premature optimization - if you're worried about performance, run a performance test first, and if you find things are slow, identify a slow area of code and improve it. A condition in a loop probably won't be the slowest area.

CertainPerformance
  • 356,069
  • 52
  • 309
  • 320