编译时哈希C++0x

Compile Time Hashing C++0x

本文关键字:C++0x 哈希 编译      更新时间:2023-10-16

使用GCC 4.4(通常是Android和IOS可用的最大值)可以在编译时对字符串进行哈希处理。

我们有一个资源管理器,它将字符串键映射到资源。虽然查找速度很快,但哈希和字符串创建速度很慢。类似于:

 ResourcesManager::get<Texture>("someKey");

花费大量时间分配字符串"someKey",然后对其进行哈希。

我想知道是否有一个技巧可以用来在编译时对它进行散列。

您必须实现正确的哈希算法,但这可以使用C++11的constexpr函数:

#include <iostream>
// Dummy hashing algorithm. Adds the value of every char in the cstring.
constexpr unsigned compile_time_hash(const char* str) {
    // Modify as you wish
    return (*str == 0) ? 0 : (*str + compile_time_hash(str + 1));
}   
int main() {
    unsigned some_hash = compile_time_hash("hallou");
    std::cout << some_hash << std::endl;
}

然后您可以有一个ResourcesManager::get的重载,它取compile_time_hash的结果(在这种情况下是一个无符号的)。

这显然取决于您所应用的哈希算法。使用constexpr实现类似SHA*的东西将非常痛苦。

请注意,您需要GCC>=4.6或clang>=3.1才能使用constexpr。

为了进行编译时哈希,所有键都需要是编译时常量。

使用编译时常量进行索引的常用方法不是使用字符串,而是使用枚举类型。这样做的优点是根本不需要散列,因为常数是顺序的,可以直接对数组进行索引。

enum KeyType
{
    someKey,
    someOtherKey
};
ResourcesManager::get<Texture>(someKey);

如果需要将键作为字符串获取,只需保留一个可以由枚举常量索引的字符串表。

static char * keyNames = 
{
    "someKey",
    "someOtherKey"
};

您总是可以编译一个程序来散列字符串并输出合适的源代码。。。

就我自己而言,我实际上并不是在散列字符串,我只是枚举项目并用枚举输出一个头文件。漂亮简单,没有碰撞等。