I did mention that I'd post on this someday.
Many years ago Jon Blossom asked me if we used STL at Treyarch. I scoffed. "I've pretty much internalized how to write a linked list," I said.
The very next week I wrote a linked list of...somethings, I forget what. Anyhow, there was a bug in there.
Oops.
So I talked Pete & Don into letting me give STL a go.
We used it fairly sparingly on Die By The Sword, and used it a lot in Draconus. There was a hump to get over, there - there was fragmentation and wastage and cache misses. We had to dig in, replace allocators, try different containers, once or twice even write our own. We, of course, got bit by all the standard things newbie STL users get bitten by - deleting a member from some containers while iterating through it often has undefined results, etc. At the time I thought maybe we made a mistake - even said something along those lines in the post-mortem - but in future projects things went much more smoothly. We knew the gotchas and could work around them.
Also - if we hadn't used STL, what were our alternatives?
Write our own container class library. We'd likely end up with something buggy, lacking in type safety, and slower than STL. And something that new talent wouldn't know how to use. Sure, not everybody we hired at Treyarch knew STL; but if we'd written our own container class libary nobody would know it.
We could use a non-type-safe container class library like Kazlib. I'm not sure Kazlib was even available back then. This might be a good alternative - but it's not type-safe and not as many people know it as STL. I've never used it, myself.
Write new container code for every class that needs it - which is what we did with Die By The Sword. The result with DBTS was that we almost always used fixed arrays with #defined MAX_SIZEs. When an array ran out of space we'd double it. Often that meant artist goes to programmer, says he needs more X, programmer ups the number, recompiles (often meant rebuilding the whole program), checks in.
So - since I'm obviously so in love with STL, you must think I'm in love with templates in general, right?
No.
I think it's almost never appropriate for us to write our own template classes.
At that Gamefest lead engineer roundtable I mentioned before - I think it was Tony Cox who said "Premature abstraction is the root of all evil."
Word.
Almost every time a clever programmer at Treyarch templatized a class we saw this pattern:
- Original programmer says, "Look how cool! Now we can extend this class to do x, y, or z trivially."
- We all agree, "Very cool!"
- We never actually extend the class to do x, y, or z.
- New talent who need to work with the code get scared of its templatey-ness and are mired for weeks or months in its grasp.
- We eventually replace the templatey code with non-templatey code that does just what it needs to do and no more.
I think it was Kent Beck who said you should refactor once you've written the same code three times. I think with templates I'd go as far as four, because they carry a lot of baggage with them - mostly of the scaring-new-programmers variety.
There's another reason you might write a new template - and that's because you want to create their own container class. In this case, you're probably going to end up with something buggier / slower than STL. I'm not saying that you're not as smart as those STL guys - I'm saying your container is less mature. STL has been in production code for years. Yours hasn't. You might say, "But I have this special need that STL doesn't fit." In which case, if it's a special need, why do you need a template for it? Write the code once. Once you've had that special need three or four times make it a template.
To sum up: STL good - mature, fast, standard - but there is that hump there. Templates bad - premature abstraction, scares new programmers.
The irony.
Recent Comments