J'ai un problème très étrange concernant l'utilisation de la fonction de hachage auto-définie dans std :: unordered_map.Hash std :: array utilisé dans std :: unordered_map
Mon type de clé est plus grand que int64, donc j'utilise std :: array pour le représenter. Pour obtenir la valeur de hachage, je crée une classe 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];
};
};
Tout d'abord, le tester:
std::array<char, 12> arr = {1,2,3,4,5,6,7,8,9,10,11,12};
MyHash o;
o(arr);
o(arr);
Il est OK. Il imprime le même t.a
et t.b
. Maintenant utiliser avec 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;
Maintenant, il imprimera error
, la raison est le t.b
en insert est différent avec find. Et cela arrive seulement en mode vs libération (ou g ++ O2)
je préfère calculer un hachage de tous les 12 octets en utilisant par exemple 'boost :: hash_range': http://coliru.stacked-crooked.com/a/cddb1ea79a18d0b1 –
D'abord je l'utilise mais j'ai trouvé que c'est un peu lent car il fera 12 fois le hash.Et la qualité n'est pas bonne en raison des 4 premiers octets dans le tableau sont presque la même valeur – jean
si les 4 premiers octets sont toujours les mêmes, vous pouvez simplement les ignorer lors du calcul du hachage ('boost :: hash_range (oid.begin() +4, oid.end()); '); Avez-vous mesuré la différence de temps? À quel point est-ce plus lent que votre approche memcpy/union? –