关于哈希的说明
Numba 支持内置的 hash()
函数,并通过简单地调用所提供参数的 __hash__()
成员函数来实现这一点。这使得为新类型添加哈希支持变得非常简单,因为所需要的只是将扩展 API overload_method()
装饰器应用于重载函数,以计算新类型注册到该类型的 __hash__()
方法的哈希值。例如:
from numba.extending import overload_method
@overload_method(myType, '__hash__')
def myType_hash_overload(obj):
# implementation details
实现
Numba 哈希函数的实现严格遵循 Python 3 的实现。唯一的例外是对于哈希 Unicode 和字节(对于内容长度超过 sys.hash_info.cutoff
),唯一支持的算法是 ``siphash24``(CPython 3 中的默认算法)。因此,在描述的默认条件下,Numba 将匹配 Python 3 对所有支持类型的哈希值。
Unicode 哈希缓存差异
Numba 和 CPython 的 Unicode 字符串内部表示都有一个 hash
成员,用于缓存字符串的哈希值。在计算哈希值之前总是会检查这个成员,以便直接从缓存中提供值,因为这样做成本要低得多。Numba 的 Unicode 字符串哈希缓存实现与 CPython 的行为类似。唯一显著的行为变化(并且其唯一的影响是潜在的轻微性能变化)是,Numba 总是在 nopython 模式
中创建的 Unicode 字符串被装箱以在 Python 中重用时计算并缓存其哈希值,这在某些情况下比 CPython 更急于计算哈希值,因为 CPython 可能会根据创建方法延迟哈希新 Unicode 字符串。还应注意的是,Numba 在将 Unicode 字符串从 CPython 的内部表示解包到自己的表示时,会复制 CPython 内部表示中的 hash
成员,以避免重新计算已经有关联哈希值的字符串的哈希值。
PYTHONHASHSEED
的适应性
PYTHONHASHSEED
环境变量可以用于为 CPython 哈希算法设定种子,例如为了重现性。Numba 的哈希实现直接读取 CPython 哈希算法的内部状态,因此 PYTHONHASHSEED
的影响在 Numba 的哈希实现中得到了复制。