Skip to content

Instantly share code, notes, and snippets.

@Giacom
Created October 31, 2018 11:50
Show Gist options
  • Select an option

  • Save Giacom/ed75af192748579863ec7fe19afd0517 to your computer and use it in GitHub Desktop.

Select an option

Save Giacom/ed75af192748579863ec7fe19afd0517 to your computer and use it in GitHub Desktop.
constexpr unsigned int length(const char* string) {
unsigned int i = 0;
while (string[i] != '\0') i++;
return i;
}
constexpr unsigned int generateHash(const char* string) {
unsigned int hash = 0;
unsigned int len = length(string);
for(unsigned int i = 0; i < len; ++i)
hash = 65599 * hash + string[i];
return hash ^ (hash >> 16);
}
// These optimisations mainly only affect Clang, GCC is sometimes clever enough to optimise this
// EXCEPTION: GCC is not clever enough to optimise it out when directly returning a function with a HASH(), i.e: return HASH("hello");
// Just uses plain old constexpr
// Requires -O2 to be optimised fully and will generate runtime code if stored into a constexpr var
#define HASH1(str) generateHash(str)
// Uses a lambda to store the hash in a constexpr context and then returns it.
// This will stop it from ever generating runtime code for generateHash()
// Pretty optimal without optimisation flags and is completely optimised in -Og
// Even more optimised if set into a variable with constexpr.
// Can clutter your code as it may have to create a lambda type everytime
#define HASH2(str) []() { constexpr unsigned int i = generateHash(str); return i; }()
int main() {
// Uncomment each section to see the code generated in gcc.goldbolt.org
// return HASH1("hello") + HASH1("there") + HASH1("how are you");
// return HASH2("hello") + HASH2("there") + HASH2("how are you");
// auto i = HASH1("hello");
// constexpr auto i = HASH1("hello");
// auto i = HASH2("hello");
// constexpr auto i = HASH2("there");
// return i;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment