• Create Account

### #ActualHodgman

Posted 22 November 2012 - 06:29 AM

Basically, these kinds of systems boil down to:
int foo = TurnStringIntoIdentifier("foo");
int bar = TurnStringIntoIdentifier("bar");
int other = TurnStringIntoIdentifier(string("f") + "oo");
bool isFoo = other == foo;
bool isBar = other == bar;
It doesn't have to be done at compile time, just as long as you're not constantly calling TurnStringIntoIdentifier. As long as you cache the result in an integer variable, then the code's gonna be faster than using string comparisons everywhere.

Aside from hashing, another way to make one of these systems is via string interning, which boils down to something like:
container<string> strings;
int TurnStringIntoIdentifier( string input )
{
if strings does not contain input then
endif
return index of input within strings
}

For a basic version using hashing, the TurnStringIntoIdentifier is just a hash function. I often use the Fnv-1a hash, but there's plenty to choose from.
The problem with this basic version is that it's possible for two strings to return the same hash, which means when you compare the integers you can get false-positives. e.g. above, isFoo and isBar could both be true!

One way to deal with this is to still perform regular string comparisons, but only when the hash compare succeeds. If the hash comparison is false, you can skip the string comparison.

Another way is to simply assume that this event will never occur
In my engine, in development builds, whenever I hash a string, I add it to a global map, with the hash as the key and the string as the value. If that key is already present in the map, then I assert that the existing value matches the string that I'm currently hashing. If this assertion fails, it means I've ended up in the unfortunate situation where two strings have generated the same hash. When this occurs, you can change the "salt" constant used in your hashing algorithm until the problem goes away.
In shipping builds, I skip this assertion checking, and assume that no strings will generate the same hash.

### #1Hodgman

Posted 22 November 2012 - 06:25 AM

Basically, these kinds of systems boil down to:
int foo = TurnStringIntoIdentifier("foo");
int bar = TurnStringIntoIdentifier("bar");
int other = TurnStringIntoIdentifier(string("f") + "oo");
bool isFoo = other == foo;
bool isBar = other == bar;
It doesn't have to be done at compile time, just as long as you're not constantly calling TurnStringIntoIdentifier. As long as you cache the result in an integer variable, then the code's gonna be faster than using string comparisons everywhere.

Aside from hashing, another way to make one of these systems is via string interning, which boils down to something like:
container<string> strings;
int TurnStringIntoIdentifier( string input )
{
if strings does not contain input then
}