# md5.py
import numpy as np
import _md5
def md5_array(data):
out = np.zeros(data.shape, dtype='|S16')
_md5.lib.md5_array(
_md5.ffi.from_buffer(data),
data.size,
_md5.ffi.cast("unsigned char *", _md5.ffi.from_buffer(out))
)
return out
和一个脚本比较两者:
# run.py
import numpy as np
import hashlib
import md5
data = np.arange(16, dtype=np.uint64)
out = [hashlib.md5(i).digest() for i in data]
out2 = md5.md5_array(data)
print(data)
# [ 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15]
print(out)
# [b'}\xea6+?\xac\x8e\x00\x95jIR\xa3\xd4\xf4t', ... , b'w)\r\xf2^\x84\x11w\xbb\xa1\x94\xc1\x8c8XS']
print(out2)
# [b'}\xea6+?\xac\x8e\x00\x95jIR\xa3\xd4\xf4t', ... , b'w)\r\xf2^\x84\x11w\xbb\xa1\x94\xc1\x8c8XS']
print(all(out == out2))
# True
要编译绑定并运行脚本,请运行
python build.py
python run.py
对于大型阵列,它大约快15倍(老实说,我有点失望……)
data = np.arange(100000, dtype=np.uint64)
%timeit [hashlib.md5(i).digest() for i in data]
169 ms ± 3.14 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)
%timeit md5.md5_array(data)
12.1 ms ± 144 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
3条答案
按热度按时间ckocjqey1#
您可以为OpenSSL的
MD5()
函数编写一个接受NumPy数组的 Package 器。我们的基线将是一个纯Python实现。创建构建器
和 Package 器
和一个脚本比较两者:
要编译绑定并运行脚本,请运行
对于大型阵列,它大约快15倍(老实说,我有点失望……)
如果您想将绑定放在库中并在安装时编译它们,请将以下内容放在
setup.py
中:idfiyjo82#
我绝对建议避免将
uint64
转换为字符串。您可以使用struct
来获取二进制数据,然后将其馈送到hashlib.md5()
:这肯定会加快这个过程,因为没有转换,只是简单的字节复制。
此外,gettig
hexdigest()
可以替换为digest()
,它返回二进制数据,这比将其转换为十六进制字符串更快。这可能是一个很好的方法,具体取决于您计划稍后如何使用这些数据。x8diyxa73#
**注意!”对不起,我错过了这个问题。下面的代码计算整个数组的MD5,没有任何转换。这东西放错地方了