Question

Let's say I have this code below:

int led = 13;

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

void loop() {
  ledChange(HIGH);
  delay(1000);
  ledChange(LOW);
  delay(1000);
}

void ledChange(int pinState)  {
  digitalWrite(led, pinState);
}

Does moving digitalWrite(led, pinState); to its own function affect processing time?

Of course, performance doesn't matter with a single LED, but it could matter when every clock cycle counts (high sampling rates, lots of math in loops, etc.).

Was it helpful?

Solution

Yes, you are wasting a teensy amount of clock cycles. When you write ledChange(LOW), it is compiled to a CALL type instruction (which tells the program counter register to jump to the location of the method).

So, this will basically compile to:

  • Put LOW in some register or the stack
  • jump to the location of ledChange()
  • Fetch led from memory, and put it along with LOW somewhere
  • jump to digitalWrite()
  • do whatever is in digitalWrite()
  • jump back
  • jump back

Note that a CALL jump involves a lot of messing with the stack, and takes a lot longer than a regular JMP instruction.

On the other hand, doing just digitalWrite(led,LOW) will do:

  • Fetch led,LOW from somewhere on the memory and put them somewhere accessible
  • jump to ditigalWrite()
  • do whatever is in digitalWrite()
  • jump back

I'm not entirely sure how arguments are passed in the corresponding compiled code, it's probably a part of the call. Also note that compilers vary, and some are smarter than others.

You can see that your encapsulation of the function made the program take up more clock cycles every time you while running it. However, this isn't really worth optimizing; I don't see much capacity in such encapsulation to slow down the Arduino. Besides, like I mentioned, some compilers optimize such things.


This has nothing to do with the function being a void. If it was an int function, it would be ever-so-slightly slower since storing the int before return involves a MV or stack operation (forgot which).

OTHER TIPS

A function being defined as void simply informs the compiler / optimizer that there is no return value expected from the function.

There will thus be no code generated for saving or manipulating any return value.

This is not Arduino specific, it is a generic C behavior.

You can setup avr-gcc to show the assembly output. Checking it out you can see that the return type of the function doesn't matter regarding the size of the code. If you don't return any value it won't generate extra code. However you will get compiler warnings, so it's nice to use void in this case.

If you use functions you will have likely shorter code, because you don't need to repeat the code in the function every time you need it (this means you'll need to have enough code in the function to offset the calls and return instructions - which is almost always the case). This will make the code slightly slower since it needs to execute the call and return instructions, however this most likely will be offset by the size reduction and the improvement in the code maintenance.

I hope I was clear enough, this seems a little convoluted :)

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top