uint32_t值对的交换散列函数
Commutative hash function for uint32_t value pairs
我需要一个快速、简单的哈希函数,为一对uint32_t
值创建一个唯一的标识符,因此(2,7)
和(7,2)
的哈希值相同。
知道吗?
要回答我自己的问题,解决方案是:
uint64_t hash(uint32_t x, uint32_t y)
{
const uint64_t a = static_cast<uint64_t>(x);
const uint64_t b = static_cast<uint64_t>(y);
if (x < y) return (b << 32) | a;
else return (a << 32) | b;
}
可以改进为无分支版本
uint64_t hash(uint32_t x, uint32_t y)
{
const uint64_t a = static_cast<uint64_t>(x);
const uint64_t b = static_cast<uint64_t>(y);
const uint64_t h0 = (b << 32) | a;
const uint64_t h1 = (a << 32) | b;
return (x < y) ? h0 : h1; // conditional move (CMOV) instruction
}
这些方法是完美的散列函数-它们保证零冲突。但是,它们的缺点是不能对2^32 - 1
以上的值进行散列。
constexpr uint32_t hash_max = ...;
constexpr uint32_t commutative_hash(uint32_t i, uint32_t j) {
return (i*j + (i*i)*(j*j) + (i*i*i)*(j*j*j)) % hash_max;
};
额外的括号用于编译器-优化此表达式会更容易。
不要使用任何条件指令(或std::max
/std::min
)如果你想做一个快速的函数,它会破坏CPU管道(而且速度很慢)。
相关文章:
- 为非标准对象定义散列函数和相等函数
- 对于自定义类的一个未定义集,是否有一个默认的散列函数
- 字典中使用了什么散列函数(hash_table)
- 指针的最快散列函数是什么
- 一个很好的向量散列函数
- 获得快速的k对独立散列函数的选项是什么
- 避免散列函数中的严格混叠冲突
- 当我在Unorder容器中使用位集时,散列函数是什么样子的
- 这个简单的散列函数背后的逻辑是什么
- 很好的散列函数可以从数组中删除重复项
- uint32_t值对的交换散列函数
- 带有自定义散列函数(bstrt)的无序映射仅适用于默认构造函数(重复键)
- 如何在散列函数中选取基数
- 使用unordered_set时,struct中嵌套结构的散列函数
- c++使用[](int i){return i;}作为unordered_set散列函数
- boost::unordered_map -- 需要为散列 std::set 指定自定义散列函数<int>吗?
- 为嵌套自定义类型定义散列函数
- 所有stl容器的通用散列函数
- 需要一个散列函数来创建ipv6 16字节地址和TCP 2字节端口号的32位值
- 使用lambda定义散列函数会引发异常