std :: unordered_mapで自己定義されたハッシュ関数を使用することについて、私は非常に奇妙な問題があります。std :: unordered_mapで使用されるstd :: arrayをハッシュします。
私のキータイプはint64よりも大きいので、私はそれを表現するためにstd :: arrayを使用します。 はそれをハッシュの値を取得するために、私はMyHashクラスを作成します。
class MyHash
{
public:
std::size_t operator()(const std::array<char, 12>& oid) const
{
Convert t;
std::memcpy(t.arr, oid.data(), 12);
std::cout << t.a <<" "<<t.b << std::endl;
return (std::hash<std::int32_t>()(t.a)^(std::hash<std::int64_t>()(t.b) << 1)) >> 1;
}
union Convert {
struct {
std::int32_t a;
std::int64_t b;
};
char arr[12];
};
};
まず、それをテスト:
std::array<char, 12> arr = {1,2,3,4,5,6,7,8,9,10,11,12};
MyHash o;
o(arr);
o(arr);
それはOKです。それは同じt.a
とt.b
を印刷します。今のstd :: unordered_mapとそれを使用します。
std::unordered_map<std::array<char, 12>, int, MyHash> map;
std::array<char, 12> arr = {1,2,3,4,5,6,7,8,9,10,11,12};
map.insert(std::make_pair(arr, 1));
auto it = map.find(arr);
if(it == map.end())
std::cout << "error";
else
std::cout << it->second;
さて、それはerror
を印刷しますが、その理由は、インサート内t.b
は検索と異なるです。そして、これだけリリースモード(またはg ++ O2)対で起こる
私はむしろ、例えば使用しているすべての12バイトのハッシュを計算したいです'boost :: hash_range':http://coliru.stacked-crooked.com/a/cddb1ea79a18d0b1 –
まず、私はそれを使用しますが、それは12倍のハッシュを行うため、少し遅いことがわかりました。そして配列の最初の4バイトのために品質が良くないのは、最初の4バイトが常に同じ場合は – jean
の値がほぼ同じです。ハッシュを計算するときにそれらをスキップするだけです( 'boost :: hash_range(oid.begin() +4、oid.end()); ');あなたは時間差を測定しましたか?あなたのmemcpy/unionアプローチよりどれだけ遅いですか? –