C++ 编译时散列C++;0x

C++ 编译时散列C++;0x,c++,compiler-construction,hash,C++,Compiler Construction,Hash,使用GCC4.4(通常是Android和IOS可用的最大值)可以对字符串进行编译时哈希 我们有一个将字符串键映射到资源的资源管理器。虽然查找速度很快,但哈希和字符串创建速度很慢。比如: ResourcesManager::get<Texture>("someKey"); ResourcesManager::get(“someKey”); 花费大量时间分配字符串“someKey”,然后对其进行哈希运算 我想知道是否有一个技巧可以用来在编译时对其进行散列。您必须实现正确的散列算法,

使用GCC4.4(通常是Android和IOS可用的最大值)可以对字符串进行编译时哈希

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

 ResourcesManager::get<Texture>("someKey");
ResourcesManager::get(“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;
}
#包括
//虚拟哈希算法。添加cstring中每个字符的值。
constexpr无符号编译时间散列(const char*str){
//随意修改
return(*str==0)?0:(*str+compile\u time\u hash(str+1));
}   
int main(){
unsigned some_hash=compile_time_hash(“hallou”);

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


我自己,我实际上并没有对字符串进行散列,我只是枚举项并输出一个带有枚举的头文件。很简单,没有冲突等。

为了进行编译时散列,所有键都需要是编译时常量

static char * keyNames = 
{
    "someKey",
    "someOtherKey"
};
使用编译时常量进行索引的常用方法不是使用字符串,而是使用枚举类型。这样做的优点是根本不需要哈希,因为常量是连续的,可以直接索引数组

enum KeyType
{
    someKey,
    someOtherKey
};

ResourcesManager::get<Texture>(someKey);

get
的参数类型是什么?为了避免分配,请使用
char const*
。如果在编译时知道密钥,为什么不使用
enum
?smoching是正确的。为什么在可以使用简单的枚举(如:
ResourcesManager::get)的情况下,执行编译时哈希会使您的生活复杂化(参考资料::SomeKey)
@DavidRodríguez dribeas,我认为对于同一字符序列的不同实例化,不能保证文本的地址是相同的。而对于仅资源,枚举是可以的。一些资源引用键来自文件,它们应该散列一次,而不是每次使用。更大的使用来自于渲染例程ac访问着色器一致性。通过字符串键查找一致性的表。这将受益于编译时哈希。您无法真正枚举此表,因为统一位置在硬件上不一致。综上所述,代码库的业务逻辑类似于脚本。保留查找的一般情况,而不是与e即使是不断增长的枚举也似乎更聪明(目前)。也许有助于澄清:constexpr函数有一个非常严格的形式,不能使用循环。这就是为什么哈希非常困难的原因。我还发现禁止循环以及什么都不允许递归是非常奇怪的。这促使我阅读了constexpr,我承认我还没有听说过。除了分析之外(valgrind、gprof等)有没有办法验证constexpr是否确实在编译时进行了计算?对不起,这不起作用。GCC 4.4不支持constexpr…@Halsafar哦,对不起,我没有注意到你在GCC 4.4中使用了它。这对那些试图在C++11中实现这一点的人很有用。供将来参考。XCode目前可以编译这一点。它似乎忽略了constexpr,或者很乐意接受它。Android仍然加入GCC4.4,所以它无法。不过谷歌确实提供了GCC4.6源代码。正在尝试编译它们。