# Thread: I am going to write a program that has hundreds of either ifs or switch case

1. ## I am going to write a program that has hundreds of either ifs or switch case

which would be faster? I do not mean compile time.

2. Measure with typical input and find out.

3. Then measure it on a different compiler, and then wonder why the answer might be different.

Some things to consider:
Are the cases compact (like 1,2,3,4) or sparse (1,100,10000,1000000)?
Are case frequencies random or biased in favour of certain values?

4. If the switch fits, you must commit.

It's hard to imagine a switch being slower than nested ifs and easy to imagine it being faster. A particularly smart compiler might transform your if into roughly the same code as the switch but if your situation fits the constraints of a switch then you should give the compiler the hint by coding it that way.

5. I just made a little program to generate two programs, one using if/else if's and the other using a switch. You then run the two programs for the same number of reps (and with the same random seed) to compare the results. Of course, this is just for a particular system with this particular (random) data, but for me the switch blows the if/else if's out of the water.
Code:
```#include <stdio.h>
#include <stdlib.h>
#include <time.h>

#define NUMSTATEMENTS   100  // default number of statements
#define RANDLIMIT    100000
#define DEFAULTREPS   10000
#define TAB "        "  // 8 spaces

void tail(FILE *f);

int *nums;
int inums = 0;

int in_nums(int n) {
for (int i = 0; i < inums; i++)
if (nums[i] == n)
return 1;
return 0;
}

int rnd() { // no repeats
int r;
do r = rand() % RANDLIMIT; while (in_nums(r));
nums[inums++] = r;
return r;
}

int main(int argc, char **argv) {
int num_statements = argc > 1 ? atoi(argv[1]) : NUMSTATEMENTS;
nums = malloc(num_statements * 2 * sizeof *nums);

srand(time(NULL));

FILE *f_if = fopen("if.c", "w");
if (!f_if) return 1;
FILE *f_switch = fopen("switch.c", "w");
if (!f_switch) return 1;

int a = rnd(), x = rnd();
fprintf(f_if, TAB "if (a == %d) x = %d;\n", a, x);

fprintf(f_switch, TAB "switch (a) {\n");
fprintf(f_switch, TAB "case %d: x = %d; break;\n", a, x);

for (int i = 1; i < num_statements; i++) {
a = rnd();
x = rnd();
fprintf(f_if, TAB "else if (a == %d) x = %d;\n", a, x);
fprintf(f_switch, TAB "case %d: x = %d; break;\n", a, x);
}

x = rnd();
fprintf(f_if, TAB "else x = %d;\n", x);
fprintf(f_switch, TAB "default: x = %d;\n", x);
fprintf(f_switch, TAB "}\n");

tail(f_if);
tail(f_switch);

fclose(f_if);
fclose(f_switch);

return 0;
}

fprintf(f,
"#include <stdio.h>\n"
"#include <stdlib.h>\n"
"#include <time.h>\n"
"\n"
"#define DEFAULTREPS  %d\n"
"#define RANDLIMIT   %d\n"
"\n"
"int main(int argc, char **argv) {\n"
"    int reps = argc > 1 ? atoi(argv[1]) : DEFAULTREPS;\n"
"    srand(argc > 2 ? atoi(argv[2]) : time(NULL));\n"
"\n"
"    int a, x, sum = 0;\n"
"    clock_t t0 = clock();\n"
"    for (int i = 0; i < reps; i++) {\n"
"        a = rand() %% RANDLIMIT;\n",
DEFAULTREPS, RANDLIMIT);
}

void tail(FILE *f) {
fprintf(f,
"        sum += x;\n"
"    }\n"
"\n"
"    clock_t t1 = clock();\n"
"    printf(\"%%.3f ms\\n\", (double)(t1 - t0) / CLOCKS_PER_SEC * 1000);\n"
"    printf(\"%%d\\n\", sum); // meaningless!\n"
"    return 0;\n"
"}\n");
}```
The files generated look like this (the above program was passed a command line value of 10 to generate 10 "statements").
Code:
```// if.c
#include <stdio.h>
#include <stdlib.h>
#include <time.h>

#define DEFAULTREPS  10000
#define RANDLIMIT   100000

int main(int argc, char **argv) {
int reps = argc > 1 ? atoi(argv[1]) : DEFAULTREPS;
srand(argc > 2 ? atoi(argv[2]) : time(NULL));

int a, x, sum = 0;
clock_t t0 = clock();
for (int i = 0; i < reps; i++) {
a = rand() % RANDLIMIT;
if (a == 41589) x = 45672;
else if (a == 68120) x = 53568;
else if (a == 22379) x = 55723;
else if (a == 28291) x = 47980;
else if (a == 92190) x = 66782;
else if (a == 15707) x = 4730;
else if (a == 90340) x = 65562;
else if (a == 3880) x = 795;
else if (a == 30637) x = 91858;
else if (a == 27698) x = 15741;
else x = 70790;
sum += x;
}

clock_t t1 = clock();
printf("%.3f ms\n", (double)(t1 - t0) / CLOCKS_PER_SEC * 1000);
printf("%d\n", sum); // meaningless!
return 0;
}

// switch.c
#include <stdio.h>
#include <stdlib.h>
#include <time.h>

#define DEFAULTREPS  10000
#define RANDLIMIT   100000

int main(int argc, char **argv) {
int reps = argc > 1 ? atoi(argv[1]) : DEFAULTREPS;
srand(argc > 2 ? atoi(argv[2]) : time(NULL));

int a, x, sum = 0;
clock_t t0 = clock();
for (int i = 0; i < reps; i++) {
a = rand() % RANDLIMIT;
switch (a) {
case 41589: x = 45672; break;
case 68120: x = 53568; break;
case 22379: x = 55723; break;
case 28291: x = 47980; break;
case 92190: x = 66782; break;
case 15707: x = 4730; break;
case 90340: x = 65562; break;
case 3880: x = 795; break;
case 30637: x = 91858; break;
case 27698: x = 15741; break;
default: x = 70790;
}
sum += x;
}

clock_t t1 = clock();
printf("%.3f ms\n", (double)(t1 - t0) / CLOCKS_PER_SEC * 1000);
printf("%d\n", sum); // meaningless!
return 0;
}```
Of course, much bigger test programs should be used (1000+ statements).

To run the generated files pass them the number of reps and a random seed (the same values to each program).