Which one is faster? Function call or conditional if statement?

Please consider branch prediction before answering this question.

I have several scenarios where I can replace a conditional statement with a function call using a function pointer. Some things like this. (you can think of component-based programming over inheritance for a similar type of senario)

class Shape { float Area() { if(type == SQUARE) { return length*length; } else if(type == RECTANGLE) { return length*breadth; } } } 

The same class can be written like this:

  class Shape { void SetAreaFunction(void *funcptr)//this function is used to set the current AreaFunc { CurrentAreaFunc = funcptr ;//this holds the pointer to current area func } float SqauareArea();//this will return square area float RectangleArea();//this will return rectangle area float Area() { currentAreaFunc(); } } 

IF you are considering the above cases, both achieve the same results. But I am thinking about increasing productivity. In the second case, I avoid the problem of predicting branching by calling a function.

Now let me know what is the best practice and “best optimized code” in such senarii. (By the way, I don’t like the statement “Pre-mature optimization is the root of all evil”, since optimization has advantages, so I think I need to optimize my code!)

PS: I don’t mind if someone gives a detailed overview of "how poor branch prediction can be" even in the assembly code.

Update: after profiling (similar code above),
If the condition is met in this form senario.Can anyone gives a reason for this? Functional calling code can be programmed, since there is no branch code? But here its appearance looks different: the winning code wins !: O Profiling on optimization Intel Mac Osx, GCC O3 / Os. A.

+4
c ++ optimization compiler-optimization architecture data-oriented-design
source share
3 answers

You have replaced the if statement with an indirect one.

Both if and indirect statements require memory access.

However, if will result in a short jump, which probably will not result in invalidation of the pipeline, while indirection may result in invalidation of the pipeline.

On the other hand, the jump is indirect, and the if statement is conditional. Branch prediction may be skipped.

It's hard to say faster without testing it. I predict that the if statement will win.

Share your results!

+9
source share

You need to comment on such code in order to be able to make a specific statement for a particular environment (compiler, compiler version, OS, hardware), and you need to measure in a specific application to know if this really matters. If you are not writing library code, do not worry, except when profiling has shown that this is a hot spot in your application.

Just write the most readable code that is easiest to maintain. It is always easier to optimize clean, error-free and easy-to-read code than to correct errors, optimized code.

However, I remember that Lippman, in his C ++ object model, referred to a study that found that virtual functions (mainly function pointers) should be at least as fast as type switching in real applications. I don't know the details, but it's somewhere in the book.

+3
source share

It is more likely that the optimizer can apply its magic to the if statement, and then to the dynamically changing function pointer. Just to guess, theoretically the compiler is allowed to do everything that he can prove, does not change the semantics.

But in case you do not call the function, but only implement the branch (using if in your case), the processor is more likely to apply its magic, that is, reorders instructions, preloading things and the like. If there is a function call between most processors, this will most likely run their pipelines, and CPU optimization will be impossible.

However, if you put everything inside the header, called and called, the compiler can end the function calls, reorder the material, etc.

Try to measure yourself. Call it 1M times. In C ++ 11, use <chrono> , monothonic_clock::now() .

Update: my experience: do not rebuild your code with my hand - it is very likely that you will make it worse. Let the compiler do the work, and for this, do as much code as possible. If you do, you definitely need a profiler, try alternatives, use the tips that some of them offer you. But do not forget: this must be carefully adjusted. Only one measure of performance is speed. There is also readability, the ability to test and reuse, and more. And to quote Donald Knuth: “Premature optimization is the root of all evil.”

+3
source share

All Articles