Jump to content

  • Log In with Google      Sign In   
  • Create Account

#ActualL. Spiro

Posted 13 November 2012 - 02:04 PM

I disagree with anyone who says either of the following:
#1: The performance is about the same.
#2: The compiler will usually generate the same code.

For #2, there is no rule that says what a compiler should do, but there are common practices that are extremely consistent between all compilers I have ever used, and as the author of MHS (Memory Hacking Software) I have done a lot of snooping around code that was compiled by compilers I have never used, still finding the exact same patterns being used.

Those patterns are explained here: http://www.altdevblogaday.com/2012/04/10/cc-low-level-curriculum-part-7-more-conditionals/
Again, no rule in the language forces this type of output, but as an unspoken rule among compilers, when possible they will all generate jump tables in order to gain in performance.
So it can’t be stated that the compiler will usually generate the same code. Just sometimes, and only if you don’t allow it to do otherwise.


Since the whole purpose of a jump table is to increase performance, #1 is also incorrect. The performance is only sometimes the same, again only if the compiler has no choice.
More accurately, “A switch case is never slower than an if-else-else-else, but sometimes (always, if you know what you are doing) faster.”
I have restricted the scope of that statement to cases in which the end result will be the same either route, since there are cases in which switch() simply can’t do the same thing as if-else-else-else, but it is assumed by the topic starter that we are only considering cases where equivalent results are possible.



All of that being said, both if-else-else-else and switch cases are often abused.
You really should only be using them if the logic changes for each case, or when the case numbers themselves are too spread apart to be able to represent with a data table or 2.
In other words, this is an abuse of a switch case (taken from that link):
int iLocal = 0;

    switch( argc )
    {
    case 0:
        iLocal = 4;
        break;
    case 1:
        iLocal = 5;
        break;
    case 2:
        iLocal = 6;
        break;
    case 3:
        iLocal = 7;
        break;
    }
This would be both faster and easier to maintain:
const static int iTable[] = {
        4,
        5,
        6,
        7,
    };
    int iLocal = iTable[argc];

Data tables are always clearer, more concise, faster, and easier to maintain/upgrade/expand in the future. They also take up less screen space, which is valuable.
You should always use them when possible.
Save switch cases for changes in logic that can’t be expressed easily by data tables or other means.


L. Spiro

#2L. Spiro

Posted 12 November 2012 - 11:12 PM

I disagree with anyone who says either of the following:
#1: The performance is about the same.
#2: The compiler will usually generate the same code.

For #2, there is no rule that says what a compiler should do, but there are common practices that are extremely consistent between all compilers I have ever used, and as the author of MHS (Memory Hacking Software) I have done a lot of snooping around code that was compiled by compilers I have never used, still finding the exact same patterns being used.

That patterns are explained here: http://www.altdevblogaday.com/2012/04/10/cc-low-level-curriculum-part-7-more-conditionals/
Again, no rule in the language forces this type of output, but as an unspoken rule among compilers, when possible they will all generate jump tables in order to gain in performance.
So it can’t be stated that the compiler will usually generate the same code. Just sometimes, and only if you don’t allow it to do otherwise.


Since the whole purpose of a jump table is to increase performance, #1 is also incorrect. The performance is only sometimes the same, again only if the compiler has no choice.
More accurately, “A switch case is never slower than an if-else-else-else, but sometimes (always, if you know what you are doing) faster.”
I have restricted the scope of that statement to cases in which the end result will be the same either route, since there are cases in which switch() simply can’t do the same thing as if-else-else-else, but it is assumed by the topic starter that we are only considering cases where equivalent results are possible.



All of that being said, both if-else-else-else and switch cases are often abused.
You really should only be using them if the logic changes for each case, or when the case numbers themselves are too spread apart to be able to represent with a data table or 2.
In other words, this is an abuse of a switch case (taken from that link):
int iLocal = 0;

    switch( argc )
    {
    case 0:
        iLocal = 4;
        break;
    case 1:
        iLocal = 5;
        break;
    case 2:
        iLocal = 6;
        break;
    case 3:
        iLocal = 7;
        break;
    }
This would be both faster and easier to maintain:
const static int iTable[] = {
        4,
        5,
        6,
        7,
    };
    int iLocal = iTable[argc];

Data tables are always clearer, more concise, faster, and easier to maintain/upgrade/expand in the future. They also take up less screen space, which is valuable.
You should always use them when possible.
Save switch cases for changes in logic that can’t be expressed easily by data tables or other means.


L. Spiro

#1L. Spiro

Posted 12 November 2012 - 06:58 PM

I disagree with anyone who says either of the following:
#1: The performance is about the same.
#2: The compiler will usually generate the same code.

For #2, there is no rule that says what a compiler should, do, but there are common practices that are extremely consistent between all compilers I have ever used, and as the author of MHS (Memory Hacking Software) I have done a lot of snooping around code that was compiled by compilers I have never used, still finding the exact same patterns being used.

That patterns are explained here: http://www.altdevblogaday.com/2012/04/10/cc-low-level-curriculum-part-7-more-conditionals/
Again, no rule in the language forces this type of output, but as an unspoken rule among compilers, when possible they will all generate jump tables in order to gain in performance.
So it can’t be stated that the compiler will usually generate the same code. Just sometimes, and only if you don’t allow it to do otherwise.


Since the whole purpose of a jump table is to increase performance, #1 is also incorrect. The performance is only sometimes the same, again only if the compiler has no choice.
More accurately, “A switch case is never slower than an if-else-else-else, but sometimes (always, if you know what you are doing) faster.”
I have restricted the scope of that statement to cases in which the end result will be the same either route, since there are cases in which switch() simply can’t do the same thing as if-else-else-else, but it is assumed by the topic starter that we are only considering cases where equivalent results are possible.



All of that being said, both if-else-else-else and switch cases are often abused.
You really should only be using them if the logic changes for each case, or when the case numbers themselves are too spread apart to be able to represent with a data table or 2.
In other words, this is an abuse of a switch case (taken from that link):
int iLocal = 0;

    switch( argc )
    {
    case 0:
        iLocal = 4;
        break;
    case 1:
        iLocal = 5;
        break;
    case 2:
        iLocal = 6;
        break;
    case 3:
        iLocal = 7;
        break;
    }
This would be both faster and easier to maintain:
const static int iTable[] = {
        4,
        5,
        6,
        7,
    };
    int iLocal = iTable[argc];

Data tables are always clearer, more concise, faster, and easier to maintain/upgrade/expand in the future. They also take up less screen space, which is valuable.
You should always use them when possible.
Save switch cases for changes in logic that can’t be expressed easily by data tables or other means.


L. Spiro

PARTNERS