Switch vs. multiple if's?

I’m working on my first game to get a handle on programming the various behaviors, and noticed something unexpected when I compile. The switch statement below compiles larger than the if/else structure. It’s only two more bytes, but I always thought that switch was more efficient. Was I wrong, or is there a rule of thumb on when to use switch vs. if/else? Or do I just need to try doing it the other way if I start running out of space and see if that helps? Thank you!

switch(colorCounter) {
case 0: setColorOnFace(BLUE,0); break;
case 1: setColorOnFace(GREEN,0); break;
case 2: setColorOnFace(RED,0); break;
case 3: setColorOnFace(CYAN,0); break;
}

if(colorCounter==0) {
setColorOnFace(BLUE,0);
} else if (colorCounter==1) {
setColorOnFace(GREEN,0);
} else if (colorCounter==2) {
setColorOnFace(RED,0);
} else if (colorCounter==3) {
setColorOnFace(CYAN,0);
}

Generally speaking, the way to figure out what is happening is looking at the assembly output for the 2 code blocks. In your specific case, it is mostly some optimization around this code that is causing what you are seeing. With this:

void loop() {
  for (byte colorCounter = 0; colorCounter < 4; colorCounter++) {
    switch (colorCounter) {
      case 0:
        setColorOnFace(BLUE, 0);
        break;
      case 1:
        setColorOnFace(GREEN, 0);
        break;
      case 2:
        setColorOnFace(RED, 0);
        break;
      case 3:
        setColorOnFace(CYAN, 0);
        break;
    }
  }
}

I get this:

Sketch uses 1470 bytes (24%) of program storage space. Maximum is 5888 bytes.

Global variables use 683 bytes (66%) of dynamic memory, leaving 341 bytes for local variables. Maximum is 1024 bytes.

And with this:

void loop() {
  for (byte colorCounter = 0; colorCounter < 4; colorCounter++) {
    if (colorCounter == 0) {
      setColorOnFace(BLUE, 0);
    } else if (colorCounter == 1) {
      setColorOnFace(GREEN, 0);
    } else if (colorCounter == 2) {
      setColorOnFace(RED, 0);
    } else if (colorCounter == 3) {
      setColorOnFace(CYAN, 0);
    }
  }
}

I get this:

Sketch uses 1470 bytes (24%) of program storage space. Maximum is 5888 bytes.

Global variables use 683 bytes (66%) of dynamic memory, leaving 341 bytes for local variables. Maximum is 1024 bytes.

As you can see, exactly the same thing (and it makes sense as either variation compiles down to the same code).

But using a switch will most likely result in more compact code in MOST of the cases.

2 Likes

And, BTW, this is better:

void loop() {
  for (byte colorCounter = 0; colorCounter < 4; colorCounter++) {
    Color color;
    switch (colorCounter) {
      case 0:
        color = BLUE;
        break;
      case 1:
        color = GREEN;
        break;
      case 2:
        color = RED;
        break;
      case 3:
        color = CYAN;
        break;
    }

    setColorOnFace(color, 0);
  }
}

This is just so you see an example of the type of optimizations you would do in Blink programs, This saves 8 bytes. :slight_smile:

Sketch uses 1462 bytes (24%) of program storage space. Maximum is 5888 bytes.

Global variables use 683 bytes (66%) of dynamic memory, leaving 341 bytes for local variables. Maximum is 1024 bytes.

Here is another example that is even better:

static const Color counterColors[] = {BLUE, GREEN, RED, CYAN};

void loop() {
  for (byte colorCounter = 0; colorCounter < 4; colorCounter++) {
    setColorOnFace(counterColors[colorCounter], 0);
  }
}

It is a lot less code and it saves… 2 bytes of storage. :slight_smile:

Sketch uses 1460 bytes (24%) of program storage space. Maximum is 5888 bytes. 

Global variables use 683 bytes (66%) of dynamic memory, leaving 341 bytes for local variables. Maximum is 1024 bytes.

The compiler is usually pretty smart about reducing code to the smallest one that still works so I would suggest you simply write your code without worrying too much about optimization and if storage becomes and issue, go back and try to optimize.

2 Likes

Thank you both for the input. In the context of my full code, the if statements saved 6 bytes over the switch, with that being the only change. Interesting about the Color object, especially with the array. I guess the differences I was seeing are due to things like use of arrays and other objects in the main code. Good point about just writing it and worrying about optimization later; I’m still struggling with the overall design of some of the things I want to do. :grin: