Take the 2-minute tour ×
Arduino Stack Exchange is a question and answer site for developers of open-source hardware and software that is compatible with Arduino. It's 100% free, no registration required.

There has been a lot of talk about shrinking sketches recently, but if you don't need the room, should it be done? Will it speed up my program?

Take this code:

int led = 13;
int val;

void setup() {                
  pinMode(led, OUTPUT);     
}

void loop() {
  digitalWrite(led, HIGH);   // turn the LED on (HIGH is the voltage level)
  delay(1000);               // wait for a second
  digitalWrite(led, LOW);    // turn the LED off by making the voltage LOW
  delay(1000);               // wait for a second

  digitalWrite(led, HIGH);   // turn the LED on (HIGH is the voltage level)
  delay(1000);               // wait for a second
  digitalWrite(led, LOW);    // turn the LED off by making the voltage LOW
  delay(1000);               // wait for a second

  digitalWrite(led, HIGH);   // turn the LED on (HIGH is the voltage level)
  delay(1000);               // wait for a second
  digitalWrite(led, LOW);    // turn the LED off by making the voltage LOW
  delay(1000);               // wait for a second

  digitalWrite(led, HIGH);   // turn the LED on (HIGH is the voltage level)
  delay(1000);               // wait for a second
  digitalWrite(led, LOW);    // turn the LED off by making the voltage LOW
  delay(1000);               // wait for a second

  val = digitalRead(10);
}

1,396 bytes on Arduino Uno. Now let's shrink it a bit:

int led = 13;
int val;

void setup() {                
  pinMode(led, OUTPUT);     
}

void loop() {
  blink();
  val = digitalRead(10);
}

void blink() {
  digitalWrite(led, HIGH);   // turn the LED on (HIGH is the voltage level)
  delay(1000);               // wait for a second
  digitalWrite(led, LOW);    // turn the LED off by making the voltage LOW
  delay(1000);               // wait for a second
}

1,270 bytes. A 10% decrease! It could be shrunk even more. I have the space... is it more efficient (as far as speed) to make it the most compact I can or leave it "uncompressed?" I would imagine that it would be a little more work (not much) calling blink();, therefore slowing down my code. Is this true? Are there other advantages/disadvantages of making it as small as possible (besides storage/distribution of C++ files)?

share|improve this question
4  
I believe that one should be fastidious about their code, but never resort to micro-optimization where unwarranted. –  Ignacio Vazquez-Abrams Mar 19 '14 at 4:26
5  
For me, what comes first regarding code is its readability. If it's longer it can be more difficult or it may take longer to understand properly. If a gvensize optimization makes the code clearer, then you should use it. –  jfpoilpret Mar 19 '14 at 6:06

5 Answers 5

up vote 6 down vote accepted

Generally speaking, smaller is better. However, there is a point where too small actually makes the program run slower.

My suggestion is if you are working on a sketch and it is blatantly obvious that you are repeating code over and over again, I would rip that out and put it into a function, not only does it make the program smaller, it makes it easier to read.

There is also some optimization going on behind the scenes as well during compilation, so even though the C/C++ code looks to be large, chances are the compiler/linker are determining that something are repeats and consolidating them... Or at least the AVR compiler I used previously did, cannot remember if Arduino does this.

share|improve this answer
    
I believe it does have some optimizations... Arduino IDE compiles with avr-gcc. –  Annonomus Penguin Mar 19 '14 at 2:08
    
Putting repeated code into a function also makes only one piece of code providing an opportunity to make mistakes, and only one one place to have to fix it/them. Also only one place to update later when you need to change something. –  JRobert Mar 19 '14 at 22:20

You second code may be smaller in size but due to the function call overhead the max execution speed is reduced.
Does this matter in your case? No, because you have huge delays anyway, but if the code was an actual series of repeated calculations that should be executed as fast as possible then it would make a difference.

As a general rule, smaller code is not necessarily faster too.

For code optimization (either size or speed) you can refer to this application note from Atmel AVR4027: Tips and Tricks to Optimize Your C Code for 8-bit AVR Microcontrollers

I could repeat everything it says here but I don't think there is a point, you can read the original article directly.


Regarding the compiler optimization level. Arduino IDE uses the avr-gcc compiler with a setting for Os optimization.
The avr-gcc available optimization levels are (source1 source2)

  • O0 or no -O option
    At this optimization level GCC does not perform any optimization and compiles the source code in the most straightforward way possible. Each command in the source code is converted directly to the corresponding instructions in the executable file, without rearrangement. This is the best option to use when debugging a program and is the default if no optimization level option is specified.

  • O1 or -O
    This level turns on the most common forms of optimization that do not require any speed-space tradeoffs. With this option the resulting executables should be smaller and faster than with -O0. The more expensive optimizations, such as instruction scheduling, are not used at this level. Compiling with the option -O1 can often take less time than compiling with -O0, due to the reduced amounts of data that need to be processed after simple optimizations.

  • O2
    This option turns on further optimizations, in addition to those used by -O1. These additional optimizations include instruction scheduling. Only optimizations that do not require any speed-space tradeoffs are used, so the executable should not increase in size. The compiler will take longer to compile programs and require more memory than with -O1. This option is generally the best choice for deployment of a program, because it provides maximum optimization without increasing the executable size. It is the default optimization level for releases of GNU packages.

  • O3
    This option turns on more expensive optimizations, such as function inlining, in addition to all the optimizations of the lower levels -O2 and -O1. The -O3 optimization level may increase the speed of the resulting executable, but can also increase its size. Under some circumstances where these optimizations are not favorable, this option might actually make a program slower.

  • Os
    This option selects optimizations which reduce the size of an executable. The aim of this option is to produce the smallest possible executable, for systems constrained by memory or disk space. In some cases a smaller executable will also run faster, due to better cache usage.

share|improve this answer
    
+1 It's better to tell the compiler to make your code bigger/faster or smaller/slower rather than doing such asinine things like needlessly unrolling loops. –  Nick T Apr 9 '14 at 0:30

When considering optimization, think carefully about what resource is most valuable.

You can optimize for code size; this will let you put more code onto your processor. What will the rest of the space be used for? If your code doesn't fit onto your arduino, and your alternative is buying a larger chip, then this is worth the effort.

You can optimize for speed - you can run more code in the same amount of time. If you are sampling data once per second, and sleeping the rest of the time, then this won't help.

You can optimize for power usage - very important if you're on a battery, less important if you are on mains. This might also not just be power consumed by the arduino, but also sensors & motors - can they be turned off for a while?

There are two optimizations that a lot of programmers forget - optimizing for development time, and optimizing for readability.

Any optimization for one thing will tend to de-optimize for at least one (often several) other things. If you don't know which optimization is going to be most useful, then go for readability, then development time (because today's readability = tomorrow's development time x 10!)

Usually, the most expensive thing is the development time (i.e. YOUR time, especially if you are on the clock for a customer). Most other optimization has a threshold - so long as you are over (under?) a specific threshold, further optimization doesn't help. Code size and execution speed (except when shared between competing tasks) are like this - if your code fits on the chip, then it is small enough. If it needs to do something else later, you can optimize it then. If your program can do all it needs to (assuming it is real-time; calculating Pi is a different case), then that's as fast as it needs to be.

share|improve this answer

Your refactor should be done simply because it's better code, not because it's smaller. The advantage is that it's easier to modify.

If making the code size smaller results in a loss of clarity (not so in your case), then you should probably view it as a premature optimization.

share|improve this answer

When your time has more worth more than the gains to be had, stop optimizing.

Are you writing for someone for pay? Then this should be their call. But in this case, readability and clarity of your code is paramount; someday, someone else will have to modify your code in your absence. If you deliver working, high performance code that someone else can't read and get a handle on, you will not have fulfilled your obligation (unless this was specifically agreed to).

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.