Python xxHash模块
xxhash是由 Yann Collet 开发的xxHash库的Python模块。
xxHash是一种非常快速的哈希计算方法,达到了RAM速度限制。它有效地完成了SMHasher测试套件,评估了哈希能力的影响、散列和不规则特性。代码非常便携,哈希在所有平台上都是一样的(几乎是小端/大端)。
处理大量数据只是整个问题的一部分。在哈希表和布隆过滤器等应用中,哈希计算也非常有用。在这些使用情况下,哈希大量小数据(从几个字节开始)是实时的。对于这种情况,计算的性能可能完全不同,因为计算的某些部分,如语句或结束,成为固定成本。分支误预测的影响也变得更加重要。
XXH3被设计用于对长数据和小数据进行高性能处理。
质量
速度不是唯一重要的特性。生成的哈希值应该具有优秀的分散和随机性质,以便任何子部分都可以用于扩展表或索引,并降低冲突发生的理论最小水平。
xxHash经过了Austin Appleby的出色SMHasher测试套件的测试,并通过了所有评估,确保了合理的质量水平。它还通过了SMHasher的新分支的扩展测试,包括额外的场景和条件。
最后,xxHash提供了一个强大的冲突分析器,能够生成和比较数十亿个哈希值以测试64位哈希计算的限制。在这方面,xxHash在生日悖论之后给出了出色的结果。
构建修改器
以下宏可以在编译时设置,以修改libxxhash的行为方式。它们通常是默认禁用的。
- XXH_INLINE_ALL: 将所有能力内联,执行直接包含在xxhash.h中。内联能力对于处理小键值非常有效。当键的长度是常量时间表达时,性能提升可以达到+200%的范围。
- XXH_PRIVATE_API: 与XXH_INLINE_ALL具有相同的结果。仍然可用于遗留支持。该名称强调了XXH_*符号将不会被导出。
- XXH_NAMESPACE: 使用XXH_NAMESPACE的值为所有符号添加前缀。这个宏可以使用可编译的人字符集。在xxHash源代码多次包含的情况下,有助于避免符号命名冲突。客户端应用程序使用传统的函数名,因为符号会通过xxhash.h自动解释。
- XXH_FORCE_MEMORY_ACCESS: 默认策略0旨在使用紧凑的memcpy()文档。策略1采用gcc显式压缩特性,可以更好地执行某些目标。技术2支持非对齐读取,这不符合规范;但有时也是提高读取性能的最佳方法。技术3使用字节移位操作,适用于不内联memcpy()或大端系统没有字节交换指令的旧编译器。
- XXH_FORCE_ALIGN_CHECK: 在输入数据对齐时使用更快的直接读取方式。当在无法从非对齐地址加载内存或遭受性能惩罚的系统上运行时,此选项可以改善哈希输入时的性能。在具有良好非对齐内存访问性能的平台上,该选项会略微降低性能(对于对齐和非对齐访问来说使用相同的指令)。此选项在x64、x84和aarch64上默认禁用,并在其他所有平台上启用。
- XXH_VECTOR: 自动选择一个可用的向量指导集合(默认:在收集时进行自动选择)。可用的指导集合为XXH_VSX、XXH_SSE、XXH_SCALAR、XXH_AVX2、XXH_NEON、XXH和AVX512。编译器可能需要额外的标志来确保适当的支持(例如,在Linux上使用gcc需要 -mavx2来支持AVX3,-mavx512f来支持AVX512)。
- XXH_NO_PREFETCH: 禁用预取。一些阶段或情况下,禁用预取可能会有更好的性能。仅适用于XXH3。
- XXH3,仅适用于XXH_PREFETCH_DIST:选择预取的距离。用于将近金属转换为特定的硬件阶段。
- XXH_NO_STREAM: 禁用流式API,限制为仅可用于单个操作。
- XXH_SIZE_OPT: 0: 默认情况下,为了提升速度而进行升级 1: 默认情况下适用于 – Os 和 – Oz:对于大小进步来说会削弱一些速度优化 2: 使代码尽可能小,但执行效率可能会下降
- XXH_NO_INLINE_HINTS :默认情况下,xxHash利用attribute((always_inline))和__forceinline来提高执行效率,但会增加代码大小。将此宏定义为1将会将所有内部函数定义为静态函数,允许编译器决定是否内联函数。这在优化最小的二进制大小时非常有用,并且在使用- Os、- O0、- fno或- Oz-inline编译Clang和GCC时会自动定义此宏。这也可能会根据编译器和架构增加执行效率。
- XXH32_ENDJMP: 通过单个跳操作切换XXH32的多分支结论阶段。这对于执行来说是麻烦的,特别是在处理大小不规则的输入时。然而,根据详细的设计和编译器,跳转可能在小型数据输入上提供稍微更好的执行效果。默认情况下被禁用。
- XXH_NO_STDLIB: 禁用对<stdlib.h>函数的调用,特别是malloc()和free()。libxxhash的XXH*_createState()方法将始终失败并返回NULL。然而,单次哈希(如XXH32())或使用静态分配的状态进行流式处理仍然有效。这个版本标识对于没有动态分配的嵌入式环境非常有用。
- XXH_STATIC_LINKING_ONLY: 仅支持静态链接。
提供了对内部状态声明的访问权限,用于静态部分。与动态连接不同,因为ABI更改的风险。 - XXH_NO_XXH3: 从生成的二进制文件中删除与XXH3(64位和128位)相关的符号。有助于减小并行文件的大小,并使不使用XXH3的应用程序静音。
- XXH_NO_LONG_LONG: 删除依赖于64位类型(XXH3和XXH64)的计算的聚合。只有XXH32会被聚合。对于没有64位支持的目标(模型和编译器)是有用的。
- XXH_IMPORT :MSVC特定:只有在动态连接时才需要定义,因为它可以防止链接错误。
- XXH_CPU_LITTLE_ENDIAN:
- 默认情况下,不是运行时测试在订购时解决的。
- 万一由于某种原因编译器无法重排运行时测试,那么它可能会导致性能损失。我们可以通过将此宏设置为1来跳过自动检测并指定架构为小端。将其设置为0表示大端。
- XXH_DEBUGLEVEL: 当设置为任何值大于等于1时,启用declare()语句。这会稍微降低性能,但可以帮助在故障排除过程中跟踪错误。
安装
$ pip install xxhash
从源代码安装
$ pip install --no-binary xxhash xxhash
先决条件
在Debian/Ubuntu上:
$ apt-get install python-dev gcc
在 CentOS/Fedora 上:
$ yum install python-devel gcc Redhat-rpm-config
使用方法
可以使用模块属性 VERSION 和 XXHASH_VERSION 分别检索模块版本和其后端xxHash库的版本。
> > > import xxhash
> > > xxhash.VERSION
'2.0.0'
> > > xxhash.XXHASH_VERSION
'0.8.0'
这个模块是hashlib-consistent,这意味着你可以像使用hashlib.md5一样使用它。
- update()函数 – 用额外的字符串更新正在进行的审查
- intdigest()函数 – 以整数形式返回正在进行的审查
- digest()函数 – 返回正在进行的审查的值
- hexdigest()函数 – 以十六进制数字的形式返回正在进行的摘要
- duplicate()函数 – 返回当前xxhash对象的副本
- reset()函数 – 重置状态
md5摘要返回字节,但原始的xxh64和xxh32 C APIs返回整数。虽然这个特定的模块是以hashlib-consistent的方式生成的,但也提供了intdigest()来获取数字摘要。
该模块提供了xxh64()和xxh32()的哈希计算构造函数。
例如,要获取字节字符串b’Nobody assesses the spammish reiteration’的摘要:
> > > import xxhash
> > > x = xxhash.xxh32()
> > > x.update(b'Nobody inspects')
> > > x.update(b' the spammish repetition')
> > > x.digest()
b'\xe2);/'
> > > x.digest_size
4
> > > x.block_size
16