Take the 2-minute tour ×
Programmers Stack Exchange is a question and answer site for professional programmers interested in conceptual questions about software development. It's 100% free, no registration required.

I am sure there is a term for the following bit of refactoring, but I can't remember it and my Google-fu is failing me!

The refactor moves if statements to where they are going to have most impact, for example changing this

$test = someFunctionThatReturnsABool();
for($x = 0; $x < 10000; $x++) {
    if ($test) { 
        echo $x; 
    }
}

To this

$test = someFunctionThatReturnsABool();
if ($test) {
    for($x = 0; $x < 10000; $x++) {
        echo $x; 
    }
}
share|improve this question
add comment

4 Answers

up vote 54 down vote accepted

This is loop-invariant code motion. A good compiler should do it on its own.

...loop-invariant code consists of statements or expressions (in an imperative programming language) which can be moved outside the body of a loop without affecting the semantics of the program. Loop-invariant code motion (also called hoisting or scalar promotion) is a compiler optimization which performs this movement automatically...

If we consider the following code sample, two optimizations can be easily applied.

for (int i = 0; i < n; i++) {
    x = y + z;
    a[i] = 6 * i + x * x;
}

The calculation x = y + z and x * x can be moved outside the loop since within they are loop invariant — they do not change over the iterations of the loop— so the optimized code will be something like this:

x = y + z;
t1 = x * x;
for (int i = 0; i < n; i++) {
    a[i] = 6 * i + t1;
}

This code can be optimized further...

share|improve this answer
55  
a good programmer should do it on it's own as well, I guess –  stijn Jul 26 '12 at 10:37
8  
I agree @stijn - there are some things that it is reasonable to let the compiler worry about, but this isn't one of them! –  Toby Jul 26 '12 at 10:48
    
@Toby: While this is true for new code (after all, the loop-invariant move makes for an easier-understood inner loop), anything that is already done by the compiler doesn't need to be done by hand. I'd just let old code such as the above example stand; the quality improvement of LICM is small and probably not worth your time. –  thiton Jul 26 '12 at 12:33
12  
@thiton I disagree. Leaving it as-is will mean all future maintainers would have to go through the same reasoning. It wastes time; just change it. –  Izkata Jul 26 '12 at 12:55
2  
@zzzzBov yes I know, but my point is that when the pattern is hidden, it probably isn't exactly the pattern anymore. Or something like that. (sorry, long day) –  stijn Jul 26 '12 at 15:13
show 7 more comments

This is also called hoisting or scalar promotion. See here:

Hoisting means that you have pulled some operation out of a loop because the loop itself does not affect the result of the operation. In your case, you are hoisting the conditional test out of the while loop.

Re-ordering means changing the sequence of instructions in a way that does not affect the result. Typically this would be adjacent instructions with no data dependencies, e.g. it does not matter which order you perform the following two statements:

int a = x;
int b = y;
share|improve this answer
add comment

I don't think such a refactoring exists.

So, it would be hard to find it amongst ''lists of refactorings''.

I'd class that example as an optimisation not a refactoring.

Refactoring, to me, is changing the code to improve its understandability without affecting its behaviour.

Optimisation, to me, is changing the code to improve performance.

Since optimised code tends to be less easy to understand. The two practices tend to work against each other.

share|improve this answer
add comment

Looks like a variant of Remove Control Flag (pp 245 of Fowler's Refactoring)

A PHP example can be found on DZone.

share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.