Challenge: Explain large code savings with the new library release

This isn’t a problem (I hope) but just an interesting question. Maybe someone who’s curious about it, or wants to show off their compiler/linker knowledge, can have a go at explaining it.

As part of creating the recent v6.0.0 release of the Arduboy2 library, I compiled and tested a fair number of existing sketches to make sure they worked identically to before. I also noted the program and RAM size differences from the previous v5.3.0 release. Program savings varied, with some saving only around 20-30 bytes and others 200-500 or more.

However, one sketch, Evasion by @obono, was far above the others, with a code savings of 2414 bytes. (The next highest savings of those I tested was 766 for SetSystemEEPROM with all others below 550.)

So, the question is: What is it about Evasion that results in such a high code savings compared to others? (I guess a pre-question is: What is actually causing the savings for all sketches? I haven’t investigated this.)

It’s probably related to the fact that the game creates a child class, MyArduboy2, which inherits Arduboy2 and overrides and adds quite a few functions.

Note that in order to get this game to compile, you’ll have to change or remove the
#if ARDUBOY_LIB_VER != 50201
test for a specific library version, at the start of file MyArduboy2.h

I’d like to investigate this myself but I spent a fair amount of time working on the new Arduboy2 release and now want to do some other things I’d set aside.

1 Like

Wow … that’s a huge saving. I can imagine when they were writing Evade they really could have used those savings!

Note that the game in question is Evasion (from the recent Game Jam 5), not the older Evade. Evade uses the original Arduboy library instead of Arduboy2.

However, with Evade converted to use Arduboy2 and ArduboyPlaytune it does pretty good as well, saving 708 bytes of code and 23 bytes of RAM (but still nowhere near as good as Evasion).

Sorry I misread that.

Thank you for your investigation about my sketch “Evasion”.

I compared the elf files: original version (using Arduboy2 v5.2.1) vs one using Arduboy2 v6.0.0.
The original version contains

  • font in “gcldfont.c” (1280 bytes)
  • write() in “arduboy2.cpp” (516 bytes, it may contain drawChar())

but another doesn’t contain them.

As you know, I customized the text-drawing function.
Therefore, the code shrinking occurred by optimization because of static declaring or refactoring write() and drawChar(), I think.

4 Likes

Thanks for looking at it.

Yes, making drawChar() static could explain it. (write() can’t be made static because it’s virtual.)

I find it strange, though, that without drawChar() being static the compiler/linker would retain the original versions of write(), drawChar() and the font table after they were all overridden in the child class. How does drawChar() being static or not influence the compiler/linker decision on whether to retain all this unused code?

Edit:
Thinking about this a bit more, it may not be making drawChar() static that causes it. It may have to do with making bootLogoExtra() non-virtual in the new release. With bootLogoExtra() virtual it may have been forced to be included, which also pulled in the code it relied on; the original versions of write(), drawChar() and the font table.

Sorry but I don’t know the detail of the behavior of the compiler/linker. :face_with_raised_eyebrow:
Anyway, the modification for v6.0.0 looks so nice.

1 Like