Why arduino is slow ?

Is Arduino really slow ?

Well that is really relative, as like everything else.  I am not talking about Time Dilation and space time fabric bending stuff here.  Alas! I haven’t seen Interstellar yet.  Anyways, this post is really about how arduino performs the basics of its function and how it appears a little slow for a little advanced users who like to get a little more fast input output response.

The How and Why ??
THE HOW :

Lets write a simple code in Arduino that sends a high pulse on pin 13 when it recieves a pulse on pin 12.

 

void setup() {
pinMode(12, INPUT);
pinMode(13, OUTPUT);
}

// the loop function runs over and over again forever
void loop()
{
if(digitalRead(12)==HIGH)
digitalWrite(13,HIGH);
else
digitalWrite(13,LOW);

}

 

As simple as this program, It is so easy to understand what we are trying to do.  We are doing nothing more than checking the digitalRead and digitalWrite functions of arduino and see how fast they act.  Lets be the doctor who whacks the knee with little hammer to get the knee-jerk reflex.

Probing the pins 12 and 13 of arduino results this :benching_digitallib

 

6.937 micro seconds!! just to do this.  We already know that AVR controller i.e. AtMega 328 is in there which runs on 16MHz clock => 62500 instructions per second if all work in one clock cycle which obviously may/may not be the case, but 62500 is the maximum for sure.

Now, Lets run the same logic but with different library.  We won’t use Arduino i.e. the libraries provided with it.  We will write in our conventional AVR studio way that avr-gcc recognizes.

 

#include <avr/io.h>
#include <util/delay.h>

enum
{
BLINK_DELAY_MS = 1000,
};

int main (void)
{
/* set pin 5 of PORTB for output*/
// DDRB |= _BV(DDB5);
DDRB |= 0b00100000;
DDRB &= 0b11101111;

while(1)
{
if(PINB & 0b00010000)
PORTB |= 0b00100000;
else
PORTB &= 0b11011111;

}

return 0;
}

Except that the size of such kind of code is extremely small as compared to the Arduino style of code because Arduino gets a lot of payload along with it for obvious reasons.

So, just burn this code up in the arduino board.
DON’T WORRY, THIS CODE WORKS FINE ON YOUR ARDUINO IDE. JUST UPLOAD IT.

And probe again the pins and here is what I got:

benching_avrlib

 

BoOOOyAA!! see, whats the surprise here.  Its the same logic implemented but with different library and it takes only 0.5 micro seconds to do the same.

THE WHY ?

The reason is pretty simple because as we know Arduino provide us with total library set that helps us to write the code while abstracting the dirty and scary details intentionally done to ease the learning curve of new comers.
They don’t need to bang their head with bit wise operators and registers addresses and yada yada.
So, they give us these functions with all the error checking to do stuff not the actual registers to work on with.
Take the simple example of digitalWrite function under your arduino directory in lib section.
Lets see the function as it is :

void digitalWrite(uint8_t pin, uint8_t val)
{
uint8_t timer = digitalPinToTimer(pin);
uint8_t bit = digitalPinToBitMask(pin);
uint8_t port = digitalPinToPort(pin);
volatile uint8_t *out;

if (port == NOT_A_PIN) return;

// If the pin that support PWM output, we need to turn it off
// before doing a digital write.
if (timer != NOT_ON_TIMER) turnOffPWM(timer);

out = portOutputRegister(port);

uint8_t oldSREG = SREG;
cli();

if (val == LOW) {
*out &= ~bit;
} else {
*out |= bit;
}

SREG = oldSREG;
}

 

Its does a lot of things, you may now see, which is unnecessarily executed everytime you call this function.  Which in other case of using AVR library where we tinker directly with registers DDRD,PORTD, timers, UDR etc.

But at the end, the development time is so drastically reduced by using the libraries and almost of the error checking already.  So, the code size and response time are relative as I said at the start.  One must decide whether to get these on the cost of ease and a little increased reliability.

On a side Note : I will recommend you to try digitalWriteFast library as it implements digitalWriteFast as a macro and does the specific work of setting the pin value.

#ifndef digitalWriteFast
#define digitalWriteFast(P, V) \
do { \
if (__builtin_constant_p(P) && __builtin_constant_p(V)) __atomicWrite__((uint8_t*) digitalPinToPortReg(P),P,V) \
else digitalWrite((P), (V)); \
}while (0)
#endif //#ifndef digitalWriteFast2

seems good enough for even for relatively new guys who start coding in arduino.  The AVRfreaks are the obvious PROs.