views:

76

answers:

4

I am micro-optimizing this function and have a bit of a problem where inside a loop I am checking if a value outside of the loop is 0, if so call function and similarly in the function it calls. How would I refactor it so there is no conditional logic (which is slow) inside these loops.

foreach($this->layer[$l]->objs as $obj) 
{
    //Horrific code to save 20ms :(
    ($l===0) ? $obj->myfunc_clean($var,$var2) : $obj->myfunc($var,$var2);
}

I need to get rid of the condition $l===0 because this condition in a loop of thousands of objects slows it down considerably. Also I have function that needs to process as normal but the other needs to unset the temp variables when it finishes (based on l being 0). The myfunc function also has a loop over yet more objects hence why I am having to call separate functions to save yet more conditional logic.

Note: This may look like premature optimization but trust me, for my application, saving one millisecond can save precious seconds (probably around 10,000 iterations if not more). So please no answers about premature optimization is the root of all evil and whatnot. This is certainly not premature.

+3  A: 

Can't you just put the test outside of the loop?

if ($l === 0)
    foreach($this->layer[$l]->objs as $obj) 
        $obj->myfunc_clean($var,$var2);
else
    foreach($this->layer[$l]->objs as $obj) 
        $obj->myfunc($var,$var2);
Wim
+1  A: 

just make two loops

if($l == 0)
  foreach(...) myfunc_clean
else
  foreach(...) myfunc
stereofrog
+1  A: 

so my quick bid is

if($l===0) 
{
   foreach($this->layer[$l]->objs as $obj)
   { $obj->myfunc_clean($var,$var2) }
}
else
{
    foreach($this->layer[$l]->objs as $obj) 
     {  $obj->myfunc($var,$var2) }
}
bakerian
not quick enough... but still + 1
stereofrog
+1  A: 

I'm assuming the condition changes during the loop, otherwise the two loops other answers provide give the answer.

Probably the condition is slow because you are making a type safe comparison (===). You might want to introduce an extra variable that is always a boolean and set at the same time of the so you can use the general comparison.

But i doubt that 10,000x times a comparison is your problem. You should probably focus on the loops inside the other functions which will be executed many more times.

Thirler
I just tried to do one million of these type-safe comparisons: .2 seconds. Use a profiler (xdebug for instance), and look where the *real* bottleneck is...
Wim
@Wim, xdebug won't give line by line performance results, just function by function. It will be useless here.
vava
@vava Not entirely useless: you can split up a function into multiple functions (one for each line, ultimately, but usually you don't need to go that far to find the offender). A bit cumbersome, I know, but usually a worthwile approach.
Wim