Thanks for all the nice comments about my last post. It’s really gratifying to get so much praise so early.
I wanted to add a few thoughts. Kermit Derren says:
I was studying something else about this on another blog… Your position on it is diametrically contradicted to what I read earlier.
He’s not criticizing me, I left out some context, go back and read the whole comment. For that matter, neither am I criticizing him. It’s just that his comment made me think a little. I can’t comment directly on the other blog, not having read it (he didn’t provide a link). I want to emphasize that it’s possible that the other blogger is right, and that I’m also right, because what your priorities are depends very much on the situation.
My aforementioned former colleague who saved two bytes wasn’t so much misguided as he was just blindly following what he’d learned early in his career. He used to work in an industry where the resources were so thin and the timing so critical that the people who wrote the code knew every detail about every operation by heart, including all affected flags, any side-effects, and how many cycles they took to run. If there were any undocumented features they doubtless knew about those as well and used them. To these people finding two extra bytes was like discovering a new seam in what they thought was a played-out mine.
I’ve never lived in that world myself, though I’ve been closer than I am now. When you’re working in sub-1K memory space your priorities are different, believe me. So while I don’t know what the blog entry actually said, I’m willing to believe that an apparent disagreement might be due to a contextual difference. Then again, maybe he really believes that saving resources is a higher priority than writing clear, maintainable code in all circumstances. Until and unless Kermit shares the link I’m reduced to guesses.
Now… since I wrote “Optimize This!” I’ve watched my own habits more closely. I’ve found myself doing the very thing I’ve criticized — re-using variables with more of a thought to saving RAM (that I usually don’t need to save) than to program clarity. When I catch myself doing that of course I immediately repent and fix the problem. Hopefully I’ll break that habit soon and instill some better habits.
We are all of us hypocrites to some degree, and I am no exception, but I like to try not to be when I can help it.
A few days ago I had a programming situation where I had three conditions, each of which would cause a behavior (send a message) but were mutually exclusive (I can only send one at a time). I assigned each flag as a bit in a byte, with the higher priority as the higher value bit. Working in assembly there are a couple ways to do this:
- An if-then-else that tests each bit and decides whether to execute the associated code.
- A jump table that depends on the value of the byte. It will of course double in size each time I add a bit.
For only three flags I had eight values, so I made it a jump table. Jump tables are pretty fast. Then I discovered two more conditions, which meant that now I had thirty-two possible combinations that started to make the jump table look a bit daunting to create and maintain.
My first reaction was to make two jump tables and therefore two decisions, to keep the ROM usage down. Then I remembered my post and stopped to actually evaluate my situation. Once I thought it through the answer was obvious. I was using about 1/4 of my total ROM so far in a project that was mostly written. 48 extra bytes (two per jump) wasn’t going to make a dent in that, it was easier to maintain a single table than two tables plus glue logic, and it would take exactly the same number of execution cycles to deal with a 32-jump table as an 8-jump table. Instead of, say, three times as many cycles, if not more, if both tables were executed. As far as generating the table goes, well, I put it together using one of my favorite tools — Excel (or an open source alternative — usually Open Office or Gnumeric). This made generating redundant entries (and counting them) and re-arranging priorities much simpler to do without making mistakes (once I had the equations fine-tuned, of course).
Of course writing the Excel equations can take more time than just writing the bloody thing by hand, but it’s less tedious and, as I mentioned, less prone to making mistakes — especially when I change things around, because if I design the spreadsheet well enough, I can change things around and the table just automatically gets fixed.
In any case, I was much happier with the result.
I really like using a spreadsheet for generating (and sometimes maintaining) lists of things. You can, for example, generate the lookup table for a curve, including DB (Define Byte) statements and tabs and comments if need be, in Excel and then copy/paste the result directly into your source code. If you make a change it just re-calculates and you just copy/paste again. Excel has some nice table lookup functions too, string manipulation, and decimal/hex conversion. You don’t really need to be an expert — learn a few tricks and you’re halfway there. I depend a lot on the built-in help and on web searches when I’m trying to learn a new feature, but none of it is difficult. Read this article by Joel Spolsky called “The Process of Designing a Product”. About halfway down he talks about discovering that people mostly use Excel to keep lists. It’s certainly true in my case, and I’m glad they focused on that functionality as a result.