No Functioncall In Loop
March 31, 2016 ยท View on GitHub
Loops are a way to execute the same instructions multiple times. That ability makes them prime candidate for optimization : the less process in a loop, the fastest the loop performs.
Avoid recounting always the same array
<?php
$x = range(1,10);
for($i = 0; $i < count($x); $i++) {
// doSomething with $i
}
?>
In the above statement, $i < count($x) is the terminal clause. It will be called after each iteration to check if the loop shall continue. Each time, it will count the number of elements in $x, even if this variable hasn't been changed. Calling count($x) may be saved by processing it before the loop, then only checking $i against a static value.
<?php
$x = range(1,10);
$count = count($x);
for($i = 0; $i < $count; $i++) {
// doSomething with $i
}
?>
This second code will do the same as the first, but speed will be dramatically increased.
##Also avoid constants expressions
<?php
$x = range(1,10);
$count = count($x);
for($i = 0; $i < $count; $i++) {
// doSomething with $i
}
?>
This second code will do the same as the first, but speed will be dramatically increased.
As a general rule, anything inside the loop (here doSomething with $i), in the terminal clause or in the incrementation clause (second and third argument to for, are worth checking for any operation that will not be affected by $i. If it is always the same, then it should be preprocessed.
Rule Details
The following code is considered a warning:
<?php
$x = range(1,10);
$count = count($x);
for($i = 0; $i < $nb; $object->methodCall()) {
// doSomething with $i and not $object
}
$x = range(1,10);
$count = count($x);
for($i = 0; $i < $count; $i++) {
$a = $object->methodCall(); // This may be processed once only
$total += $i * $a;
}
?>
The following pattern is considered legit:
<?php
// here, the condition changes as the loop is process. This is needed
$x = range(1,10);
$j = array();
for($i = 0; $i < count($j); $i++) {
// doSomething with $i and $j
}
?>