It had to happen: the STL rant
It’s not just that I don’t like the STL, it’s simply that I don’t need it.
If I need a basic container (linked list, vector…), the STL doesn’t help much because I can use my good old versions from 10 years ago.
If I need a more advanced container (e.g. a map), the STL doesn’t help much because custom versions are way faster anyway.
If I need a sort, I usually want a radix. Here again the STL doesn’t help.
If I want to disable exceptions for performance reasons, the STL doesn’t help.
If I want to save memory, the STL definitely doesn’t help.
If I want to debug my code easily, if I want to avoid “byzantine syntax” in my code, if I want to keep my compile times low or avoid insane code bloat, again, the STL fails.
So, really, why exactly should I bother? Just because it’s “standard” ? Are you insane? What does that buy me exactly? Isn’t that a lot of troubles for very dubious benefits?
STL horror stories on top of my head:
- the “contact stream” in the old Novodex SDK: we needed a dynamic vector where we could push_back both floats and ints (something like an int encoding a number of floats, followed by the actual floats). It was originally implemented with a templated array. Replacing it with a vanilla Container from ICE reduced the exe size and gave a small framerate boost.
- the VC6 implementation was a joke, but the new ones aren’t that much better. The bug is in the template theory: everything is (or can be) inlined. Take a simple push_back. It really has two parts: the one that copies the object to the dynamic array, and the one that resizes the array. Most of the time, say for a vector of ints, you really want the copy to be inlined (it just copies an int after all). However you never want the resizing part to be inlined: it happens rarely, and it’s so slow anyway that inlining it is pretty useless. But how does the compiler know that one part should be “always” inlined, while the other should not? Exactly: it doesn’t. So what do you think happen? Could you swear that the compiler will not happily inline both parts for every push_back in your code? I saw it happen with VC6. Could you swear it doesn’t happen with, say, PS3 compilers?
- speaking of which, can you guess how much we saved on the exe size a few weeks ago on PS3, when we switched from the default STL implementation to uSTL ? Hint: give your answers in megabytes.
Please use and abuse the STL, it makes my life that much easier when it comes to beating the competition. Maybe exceptional products are not written with “standard” code, you know…
March 4th, 2008 at 10:00 pm
The only interesting idea/feature of STL imho was iteration of vectors (as in “dynamic arrays”). But it felt much more elegant to do iterations like this:
foreach(AllWindows,CWindow*){
edx->TryToPaint();
}
foreach(ShortcutMgr_AllShortcuts,CallBackInt*){
if(edx->int0==key)proc=edx->proc;
}
#define foreach(_ObjVector,_Type0) for(_Type0* EDXPTR=(_Type0*)(_ObjVector)->data;_Type0 edx = *EDXPTR++;)
class ObjVector{
public:
int num;
void** data; // zero-terminated
ObjVector();
~ObjVector();
void add(void* d);
void delete(void* d);
….
};
(plus 1-2 other similar classes/macros)
April 3rd, 2008 at 11:09 am
I have a love and hate relation-ship with STL. I used to do a lot of optimization of foreign code-bases and STL abuse often was one thing I could easily remedy. Even if I didn’t go as far as replacing vectors with plain arrays.
I usually did this by just replacing maps with sorted vectors, pre-allocating the vectors to be the correct size, etc…
Then I would come to code-bases that basically implemented STL themselves. This lead to other problems:
1) I had to learn their container classes and figure out where the gotchas were.
2) Often there were subtle bugs with the container classes that took quite a long time to find.
3) Quite often STL was actually faster than these home grown containers.
Now obviously in this case the home-grown containers are really the same thing as the STL - some kind of templated, growable, container code; however, in these cases I often wished people had used STL because at least then I could have immediately spotted the problems introduced into the code.
Having said that, in my own run-time code I usually attempt to steer away from using vectors and just work with plain-fixed-size arrays myself.
Phil