Which 'library' is smaller?

Which ‘library’ is smaller?
We get asked sometimes whether FastLED is bigger or smaller than the Adafruit Neopixel library, and the definitive answer is: it totally depends on what you’re doing with it, but the same animation is probably going to be smaller with FastLED.

TL;DR: a totally empty sketch is 0.6K smaller with the Adafruit Neopixel library, but even simple animations usually compile to smaller code using FastLED, and the amount of coding that you have to do is often much less, too, and those two things are related.

You only pay for what you use
The first thing to remember is this: aside from certain ‘core’ functionality, the compiler only includes code that you’re actually using in what gets uploaded to your Arduino. So if you don’t use trig functions, they don’t take up any space. Ditto everything else: if you’re not using it, it doesn’t ‘cost’ you anything. And this is part of why the answer is “it depends”. FastLED provides all kinds of functionalities, but aside from a small core, they don’t ‘cost’ you anything if you don’t use them.

What it really comes down to is this: what is your animation doing, and how is it doing it? Are you using code you wrote yourself (which takes up space), or code that is available in the library (which also takes up space)? And which code is smaller and faster for getting the same job done?

With all those caveats out of the way, I’ll go out on a limb here and say that often FastLED will let you write a given animation faster and smaller than you could write it using just “C” and the Adafruit library. One main reason why that’s often true (not always, but often), is that FastLED includes compact assembly-language code (for both AVR and ARM) for doing things that would be bulkier and slower to do in “C”. And also because we’re obsessed.

Barest minimum sketch: Neopixel version is smaller
Let’s start by look at the very, very barest core. Let’s consider the barest minimum sketch to be this: initialize one strip of WS2811 “NeoPixels”, set one single pixel’s color to red, and show it. In this artifically minimal example, the sketch using the Adafruit library is smaller by about 0.6K.

But that’s just where the story starts (unless that’s all you want to do: light one LED red). Suppose that you want to use the brightness controls that the two libraries offer; most people do use these.

// Adafruit Neopixel library
strip.setBrightness( 128); // Adds 310 bytes

// FastLED
FastLED.setBrightness( 128); // Adds just four bytes

The non-destructive master brightness control is part of the FastLED core. If you use the brightness function, the code size of difference between these two minimal sketches just got a lot smaller. (We won’t get into the fact that the FastLED version is essentially instantaneous and that it doesn’t modify the LED buffer.)

A simple animation: FastLED version is smaller
Now let’s pick a still-very-small, but slightly more realistic sample sketch: random color twinkles that fade out. Basically you want to fade all the existing pixels a little, pick a new random location on the LED strip, and add a new random color on top of whatever’s already there. Simple and pretty. Here’s what that looks like with FastLED:

void loop() {
fadeToBlackBy( leds, NUM_LEDS, 25);
int i = random16(NUM_LEDS);
leds[i] += CHSV( random8(), 255, 255);
FastLED.show();
}

You’d have to write about six lines of code, your entire sketch would be about twenty lines total and it would compile to 3748 bytes.

With the Adafruit library, your sketch would look something like this. I apologize for the long codepaste, but I want to illustrate a point here.

void loop() {
FadePixels(25);
int i = random(strip.numPixels());
AddColorToPixel( i, Wheel( random(256)));
strip.show();
}

void AddColorToPixel( uint8_t i, uint32_t newcolor)
{
uint32_t existing_color = strip.getPixelColor( i);
uint8_t existing_red = (existing_color >> 16) & 0xFF;
uint8_t existing_green = (existing_color >> 8) & 0xFF;
uint8_t existing_blue = (existing_color >> 0) & 0xFF;
uint8_t newcolor_red = (newcolor >> 16) & 0xFF;
uint8_t newcolor_green = (newcolor >> 8) & 0xFF;
uint8_t newcolor_blue = (newcolor >> 0) & 0xFF;
uint16_t new_red = existing_red + newcolor_red;
if( new_red > 255) {
new_red = 255;
}
uint16_t new_green = existing_green + newcolor_green;
if( new_green > 255) {
new_green = 255;
}
uint16_t new_blue = existing_blue + newcolor_blue;
if( new_blue > 255) {
new_blue = 255;
}
strip.setPixelColor( i, new_red, new_blue, new_green);
}

void FadePixels( uint8_t fadeAmount)
{
for( uint16_t i = 0; i < strip.numPixels(); i++) {
FadeOnePixel( i, fadeAmount);
}
}

void FadeOnePixel( int i, uint8_t fadeAmount)
{
uint32_t existing_color = strip.getPixelColor( i);
uint8_t existing_red = (existing_color >> 16) & 0xFF;
uint8_t existing_green = (existing_color >> 8) & 0xFF;
uint8_t existing_blue = (existing_color >> 0) & 0xFF;
uint8_t new_red = (existing_red * fadeAmount) / 256;
uint8_t new_green = (existing_green * fadeAmount) / 256;
uint8_t new_blue = (existing_blue * fadeAmount) / 256;
strip.setPixelColor( i, new_red, new_green, new_blue);
}

uint32_t Wheel(byte WheelPos) {
if(WheelPos < 85) {
return strip.Color(WheelPos * 3, 255 - WheelPos * 3, 0);
} else if(WheelPos < 170) {
WheelPos -= 85;
return strip.Color(255 - WheelPos * 3, 0, WheelPos * 3);
} else {
WheelPos -= 170;
return strip.Color(0, WheelPos * 3, 255 - WheelPos * 3);
}
}

As you can see, you’d have to write about sixty lines of code yourself because things like “fading” and “HSV colors” aren’t included in the library.

But what about the compiled code size? Well, let’s look: the compiled sketch built using FastLED was 3748 bytes. The compiled sketch built using the Adafruit Neopixel library is now larger, at 3772 bytes. The FastLED code is not only much smaller to write (and read), but it compiles to smaller code as well. And consider that this is still pretty much a very simple animation: a few lines, under 4K of compiled code, and it’s not doing anything super fancy. And again, we won’t get into color space differences, etc. We’re just comparing sketch size for code that does more-or-less the same thing, and the FastLED version is smaller.

FastLED animations: often smaller
In general, if you’re writing a new animation, you’ll probably find results similar to what we’ve shown here: it’s quicker to code your animation with FastLED, and compiles to smaller code than the same animation implemented using the Adafruit Neopixel library. This is not always the case; this isn’t magic, it’s just compilers and code. If you’re not using HSV colors or pixel fading or fast random numbers or any of the other things that FastLED offers, you may get that 0.6K smaller code with the Neopixel library, which may be exactly what you need. But in general if you’re doing an interesting or sophisticted or colorful animation, FastLED may give you smaller code overall.

Topics for another day: which library runs faster, and which one lets you code faster. No spoilers, please! :wink:

There is one definite case where FastLED (currently) takes up more program space than the Adafruit Neopixel library: running multiple LED strips of the same kind on different pins, as was recently discussed here: https://plus.google.com/102483892501686823436/posts/BDKFJT4YUZq It’s worth calling it out here in case anyone else runs into that.

Good idea, and thank you!
Added to “Best of FastLED Discussions” https://github.com/FastLED/FastLED/wiki/Best-of-FastLED-Discussions

Also worth noting: Adafruit (which is an awesome group of people, doing great work, and on whom I spend a nontrivial amount of my paycheck) has a separate library for “graphics”, apart from the Neopixel driver library. Their “GFX” library is where you might find code to help you create animations, vs the “Neopixel” library itself. (And IIRC, @Daniel_Garcia has made contributions to that library to speed it up.)

In both cases, the dominating factor in RAM use is the number of pixels (times three bytes each). Other than that, FastLED is a few bytes bigger to support things like color correction. But for any project of scale, the pixel buffer is the issue.

Hmm, this is “nice” to know :wink: But the things that made me choose FastLED was the fastmath and all the other “addons” i could do the fadeToBlackBy() code example myself, as it´s straightforward and that is very nice…but i won´t be able to do the code with that neopixel library anyway anyhow, without help. it took me about 5minutes just to understand how this works.
That´s one reason why i chosen FastLED, but the most important reason are these incredible fastmath…

I know that my comment has nothing to do with your intention for this thread, it´s just my point of view…:wink:

Thanx for FastLED! :smiley: