Optimization priorities

When attempting code optimization for either a plugin or Kaleidoscope itself, what should the priorities be? I have some guesses, but I’d like to know from the people who are much more expert than I am. Here are my guesses, ranked in order from most important to least:

  1. Space used in RAM
  2. Space used in PROGMEM
  3. Space used in EEPROM
  4. Execution speed

I’m much more used to high-level, interpreted languages running on hardware that’s powerful enough that performance isn’t an issue for the programs that I write, so I’m usually much more focused on clarity of the code than any of these things. I still feel strongly that code clarity is very important, but I also think I’ve heard that some people have been running out of space with their sketches, so when I’m looking things over I’m starting to try things out that might improve at least the footprint, and I’m interested in which things deserve focus the most.

1 Like

I’m afraid the answer will be: “it depends”. There is a finite amount of each of those resources, with EEPROM being the smallest. I usually try to strike a balance. Like, if you can save 10 bytes of RAM at the cost of a hundred PROGMEM, that’s not worth it usually. If you can save 10 RAM at the cost of 10 EEPROM, that may worth it, if the thing you are putting in EEPROM is supposed to survive a reboot. Usually, when putting things into EEPROM, I consider the savings in PROGMEM.

Execution speed is also an important factor, because even if we’re not building the fastest keyboards ever, we do want to be competitive. If we are an order of magnitude slower than anyone else, then all the code clarity, all the space savings matter little.

So, try to find a balance. I can’t tell how, or what that balance is. It varies a lot, from use case to use case, and you have to weigh the costs on a case-by-case basis. I do not think there is a general RAM > PROGMEM > EEPROM > speed rule, or anyhting like it. It all depends on how much of the others it would cost to save some on one.

Yeah, I’m close to the limits:

- Size: firmware/algernon/algernon-0.0.0-g9bb7-dirty.elf
  - Program:   28078 bytes (97.9% Full)
  - Data:       1889 bytes (73.8% Full)

And I have 40 bytes of EEPROM free. And this is with my keymap in EEPROM. Otherwise PROGMEM would likely overflow.

Well, I’ve got some changes that can save >200 bytes of PROGMEM and counting, and probably have a small performance benefit, though that’s not so easy to measure. The downside is that they’re not backwards-compatible…

Do you think it’s worth it to look for things like the PR I submitted yesterday, that saves a few bytes here or there?

Perhaps we can make it backwards compatible… at the cost of no savings, if the compatibility functions are used, and increased size if both are. That would - in my opinion - be a reasonable thing.

Yes.

My original stab at this was:

Though reading it, it’s at a different level in terms of prioritization.

As @algernon says, “it depends.” But readability and maintainability are often more important than wringing every byte and cycle out of the code. In cases where we’re doing icky things for the sake of perf, they’re going to have to be very well commented and very cleanly written.

3 Likes