3

Consider a scenario, where A occurs frequently like 4 out 5 times, and B only in rare cases, we can write our conditional statement in two ways:

if(A) 
//do something
else
// do something if B, only rarely

Or we can reverse it

if(B)
//do something rarely
else
// do something with A frequently

I know that in low-level languages the order matters, especially with lot of branching, but is something like this even marginally worth it in languages like PHP etc.?

  • 5
    Possible duplicate of Is micro-optimisation important when coding? – gnat Nov 21 '16 at 13:53
  • 1
    @gnat None of the answers in that question answer my question directly – The Law Nov 21 '16 at 13:54
  • 2
    This sounds like something that would be very easy to test. – Dan Pichelman Nov 21 '16 at 13:59
  • 3
    If if has any timing impact, you probably have a strange program (imagining what communication and I/O takes in comparison). – qwerty_so Nov 21 '16 at 14:11
  • 3
    @TheLaw the answers in the link gnat posted answer it indirectly - The amount of times the code needs to be run before the time you spent asking this question is overtaken by the speedup of the "faster" method is in the order of trillions of times – Caleth Nov 21 '16 at 16:52
2

This is not meant to be a slant on PHP but if you're worried about static branch prediction in it, something is probably seriously wrong. Even the most metal-scraping C code often doesn't benefit that much, if any, from it, and the people who focus on that sort of thing are usually zoomed in at the most micro-levels analyzing assembly code and measuring repeatedly with fancy tools to guide their decisions. I wouldn't worry about it even if you want to micro-optimize. It's a bottom priority type of thing even when you're getting really micro with your optimizations.

Focus first and foremost on locality of reference with memory access patterns if you want to go micro. That can make 10x to 100x speed improvements without an improvement to algorithmic complexity. I don't even think it's fair to call them "micro" since something that improves a user-end operaton's speed by 100 times is far from "micro" in impact.

But static branch prediction? You're playing a lottery with that stuff unless you're a complete expert when it comes to assembly, profiling, and computer architecture. I often find any attempts at programming for static branch prediction even in C with VTune in hand for the hottest paths to have negligible effects, even in the tightest loops, and sometimes, counter-intuitively, even negative effects for reasons I don't have sufficient expertise to understand. I hope you don't mind but I'm assuming you also lack such expertise or else this question probably wouldn't be raised, at which point I'd suggest to focus on making your code as easy for you to manipulate as possible without worrying about static branch prediction so that you can prioritize the big stuff like algorithmic improvements, memory access patterns, and parallelism.

1

When it comes to micro-optimizations and non-compiled languages, don't worry about it. The amount of overhead that is added on by not using a compiled program will overshadow any attempts at "low level" efficiency.

However in the context of your question I've found that 'if'-ing the rarer case turns out to be better code. For instance

/* Code that both cases share */
if(rare)
{
    // Code that only the rare case needs
}
/* Code that both cases share */

Is much more readable then

/* Code that both cases share */
if(common)
{
    // Code that only the common case uses
}
else
{
    // Code that 'anything else' would use
}
/* Code that both cases share */
  • 2
    your examples are of different semantics (in general). Only when // Code that only the common case uses is empty are they the same – Caleth Nov 21 '16 at 16:49
-1

To start this kind of micro-optimization in any language is probably not worth it. A comparisons in BigO is O(1) no matter what. Write what is readable.

You can pretty easily run some basic benchmark for this. I do not have access to PHP right now but created the below tests for python (also interpreted).

Loop 1000 times finding anything in the range 1 - 100000 that is dividable by 5000.

Not rare case first

import time
import statistics as s
if __name__ == '__main__':
    times = list()
    for on in range(1,1000):
        count = 0
        start_time = time.time()
        for n in range(1,100000):
            if(n%5000 != 0):
                count += 1;
            else:
                count -= 1

        times.append(time.time() - start_time)
    print(s.mean(times))

Rare case first

import time
import statistics as s
if __name__ == '__main__':
    times = list()
    for on in range(1,1000):
        count = 0
        start_time = time.time()
        for n in range(1,100000):
            if(n%5000 == 0):
                count += 1;
            else:
                count -= 1

        times.append(time.time() - start_time)
    print(s.mean(times))

Respective outputs

not rare - 0.022764320488090628

rare - 0.02187611677267172

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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