5

GCC 4.4 (通常、Android および IOS で利用可能な最大値) を使用すると、コンパイル時に文字列のハッシュを行う方法があります。

文字列キーをリソースにマップするリソース マネージャーがあります。ルックアップは高速ですが、ハッシュと文字列の作成は低速です。何かのようなもの:

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

文字列「someKey」を割り当ててからハッシュするのに多くの時間を費やします。

コンパイル時にハッシュするために使用できるトリックがあるかどうか疑問に思っています。

4

3 に答える 3

7

正しいハッシュ アルゴリズムを実装する必要がありますが、これは 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;
}

次に、(この場合は unsigned)ResourcesManager::getの結果を取るオーバーロードを持つことができます。compile_time_hash

これは明らかに、適用しているハッシュアルゴリズムによって異なります。constexpr を使用して SHA* のようなものを実装するのはかなり面倒です。

constexpr を使用するには、GCC >= 4.6 または clang >= 3.1 が必要であることに注意してください。

于 2012-07-09T18:45:48.887 に答える
2

コンパイル時のハッシュを行うには、すべてのキーをコンパイル時の定数にする必要があります。

コンパイル時の定数でインデックスを作成する通常の方法は、文字列を使用するのではなく、列挙型を使用することです。これには、ハッシュをまったく必要としないという利点があります。これは、定数がシーケンシャルであり、配列に直接インデックスを付けることができるためです。

enum KeyType
{
    someKey,
    someOtherKey
};

ResourcesManager::get<Texture>(someKey);

キーを文字列として取得する必要がある場合は、列挙定数によってインデックス付けできる文字列のテーブルを保持してください。

static char * keyNames = 
{
    "someKey",
    "someOtherKey"
};
于 2012-07-09T18:58:49.327 に答える
0

プログラムをいつでもコンパイルして、文字列をハッシュし、適切なソースコードを出力できます...

私自身、実際に文字列をハッシュしているわけではありません。項目を列挙し、列挙されたヘッダー ファイルを出力するだけです。素晴らしく簡単で、衝突などはありません。

于 2012-07-09T18:48:50.690 に答える