Sometimes, it’s nice to be able to identify things by name, rather than using a number or an enum. The problem is, that if you’re not careful, using strings can take a lot of memory, and LOADS of CPU-power, with all the stricmp’s. When I was hired for the Tycoon City project, and assigned the task of speeding up the game (which was *really* slow at that point), it turned out they were using several hundred megabytes for storing strings (of which most were used as ID:s, and was mostly duplicates of duplicates), and that string comparisons and string copying was right at the top of the profiling results. I won’t go into how we went about solving that particular problem – it was late in the project, and things turned out the way they turned out – but it got significantly faster and smaller, that’s for sure.
Ever since then, I’m always a bit wary about using strings – it can easily get out of hand, and it feels wrong to waste both memory and CPU-power on something if you don’t have to. So, I thought I’d share my own system for solving this problem, extracted from my (recently cleaned up) Pixie Game Engine. It’s a solid, fast solution, ready to just drop into any project, and consists of only two classes. At its core is a class I call StringId, which is easily created by:
StringId myStringIdVariable("myOwnIdNameHere");
Which internally results in the string "myOwnIdNameHere" being located in a global string table (non-case-sensitive), or inserted if it’s not already added. The lookup is done through a pretty fast hash-table. In the StringId object is stored a pointer to the shared string, so you can do:
if (myStringIdVariable==anotherStringIdVariable)
and know that it will result, internally, in just a comparison of two pointers. Nice and fast. And takes less memory too, as a string is only stored in one place – the global string table. There’s also a couple of macros defined (they’re nifty at times), strSwitch and strCase, which can be used to compare StringId’s in a way similar to switch-case statements:
strSwitch (myFruitTypeStringId) { strCase(Apples) { // code to do stuff here } strCase(Oranges) { // code to do other stuff here } }
Which is the same as doing this, but looks a bit nicer (though that is, of course, a matter of taste
)
static StringId applesId("Apples"); if (myFruitTypeStringId==applesId) { // code to do stuff here } static StringId orangesId("Oranges"); if (myFruitTypeStringId==orangesId) { // code to do other stuff here }
The code is well-written and well-commented, and can be downloaded here. It is C++, and as usual it’s public domain – use it anyway you like




