By default in the switch enclosure

Below is the code that I need to optimize and plan, so that it would be useful to move on to switching. But I can compare to the case. Therefore, I planned to make comaparision (len> 3) a standard case.

If I make the comparative part (len> 3) by default and add the default, like the first in swith, will it be faster?

Or how can I make the code below as a switch statement?

if ( len > 3 ) { which will happen more often; } else if ( len == 3 ) { next case which may occur often; } else if ( len == 2 ) { the next priority case; } else { and this case occurs rarely; } 
+4
c ++ c switch-statement if-statement
Dec 28 '12 at 7:24
source share
6 answers

Probably not. Both if...else and switch...case are high-level constructs. What slows you down is branch prediction. The better your forecast, the faster your code will work. You should put your most common case in the first if , the second in else if , etc., as you wrote. For switch result depends on the internal implementation of the compiler, which can change the order of things, despite your own order. default should actually be reserved for less common situations, because the rest of the conditions must be checked before returning to default .

To do all this, using if...else in terms of performance is optimal if you set your conditions in the correct order. As for switch...case , this compiler is specific and depends on the applied optimizations.

Also note that switch...case more limited than if...else , since it only supports simple comparison of values.

+6
Dec 28 '12 at 7:32
source share

Although you agreed that probably the best answer, I would like to provide an alternative.

Please note that the standard disclaimer applies - optimization is not optimization unless you have profiled your code.

However, if you encounter poor performance related to branches, you can reduce or eliminate them. The fact that your code has one or more inequality comparisons is not an obstacle - you can reduce your cases to a set of direct equalities and, if necessary, use this to index the table, and not to branch at all.

 void doSomething(int len) { static const char* str[] = { "%2d > 3\n", "%2d < 2\n", "%2d = 2\n", "%2d = 3\n" }; int m1 = (len-2)>>31; int m2 = (len-4)>>31; int r = (len & m2 & ~m1) + !!m1; printf(str[r],len); } 

Please note that these codes make several assumptions that may not be implemented in practice, but since we make a wild assumption that this even requires optimization in the first place ...

Also, note that better optimization may be possible with more knowledge about the actual range and type of input parameter, and indeed, what actual actions need to be performed.

+3
Dec 28
source share

you cannot move comparisons to a switch statement. He uses single checks for his choices .. ie:

 switch (len) { case 1: // do case 1 stuff here break; case 2: // do case 2 stuff here break; case 3: // do case 3 stuff here break; } 

use breaks to prevent case statements from executing with each other. here

your code will be "optimized" because it will be in its current state.

+2
Dec 28 '12 at 7:28
source share

If you are worried about speed, the truth is that your if...else or switch...case will not have a real impact on the speed of your application unless you have hundreds of them. The places where you lose speed are in your iterations or loops. To specifically answer your question, you cannot convert your if...else to a switch...case with default first occurrence; but with that being said, if you made the conversion to switch...case , then you will have them to work at the same speed (the difference is too small to be picked up by conventional benchmarking tools).

+1
Dec 28
source share

The only way you are going to know is to compare it with your compiler. If performance is a problem, you should use the option to give the compiler output from the profiler and let it solve; he will usually find the best solution. (Note that even for a specific architecture, such as Intel, the best solution in terms of machine instructions may differ from one processor to the next.)

In your case, the switch will probably look like this:

 switch ( len ) { case 2: // ... break; case 3: // ... break; default: if ( len > 3 ) { // ... } else { // ... } } 

With only two effective cases, the compiler doesn't have much to work with. A typical implementation (without extreme optimization) will check the boundaries, then search the table for two obvious cases. Any worthy compiler will then select that the comparison in your case, default corresponds to one of the estimates already verified, not duplicated. But in only two cases, the transition table will probably not make a significant difference compared to the two comparisons, especially since you will be outside the most common cases.

As long as you have the actual profiler information that this is a bottleneck in your code, I would not worry about that. Once you have this information, you can look at various options to see what happens faster, but I suspect that if you use maximum optimization and feed profiling back to the compiler, there will be no difference.

+1
Dec 28 '12 at 10:50
source share

You can use a range in case of:

 switch (len) { case 3 ... INT_MAX: // ... break; case 2: // ... break; default: // ... break; } 

Edit: but this is an extension provided by GCC ...

0
Dec 28
source share



All Articles