【发布时间】:2014-03-25 03:04:04
【问题描述】:
我刚刚发现 python hashlib.md5 可能比 coreutils md5sum 快。
python 哈希库
def get_hash(fpath, algorithm='md5', block=32768):
if not hasattr(hashlib, algorithm):
return ''
m = getattr(hashlib, algorithm)()
if not os.path.isfile(fpath):
return ''
with open(fpath, 'r') as f:
while True:
data = f.read(block)
if not data:
break
m.update(data)
return m.hexdigest()
coreutils md5sum
def shell_hash(fpath, method='md5sum'):
if not os.path.isfile(fpath):
return ''
cmd = [method, fpath] #delete shlex
p = Popen(cmd, stdout=PIPE)
output, _ = p.communicate()
if p.returncode:
return ''
output = output.split()
return output[0]
关于我计算 md5 和 sha1 的测试结果时间有 4 列。
第 1 列是 coreutils md5sum 或 sha1sum 的计算时间。
第 2 列是 python hashlib md5 或 sha1 的校准时间,通过读取 1048576 块。
第 3 列是 python hashlib md5 或 sha1 的校准时间,通过读取 32768 块。
第 4 列是 python hashlib md5 或 sha1 的校准时间,通过读取 512 块。
4.08805298805 3.81827783585 3.72585606575 5.72505903244
6.28456497192 3.69725108147 3.59885907173 5.69266486168
4.08003306389 3.82310700417 3.74562311172 5.74706888199
6.25473690033 3.70099711418 3.60972714424 5.70108985901
4.07995700836 3.83335709572 3.74854302406 5.74988412857
6.26068210602 3.72050404549 3.60864400864 5.69080018997
4.08979201317 3.83872914314 3.75350999832 5.79242300987
6.28977203369 3.69586396217 3.60469412804 5.68853116035
4.0824379921 3.83340883255 3.74298214912 5.73846316338
6.27566385269 3.6986720562 3.6079480648 5.68188500404
4.10092496872 3.82357311249 3.73044300079 5.7778570652
6.25675201416 3.78636980057 3.62911510468 5.71392583847
4.09579920769 3.83730792999 3.73345088959 5.73320293427
6.26580905914 3.69428491592 3.61320495605 5.69155502319
4.09030103683 3.82516098022 3.73244214058 5.72749185562
6.26151800156 3.6951239109 3.60320997238 5.70400810242
4.07977604866 3.81951498985 3.73287010193 5.73037815094
6.26691818237 3.72077894211 3.60203289986 5.71795105934
4.08536100388 3.83897590637 3.73681998253 5.73614501953
6.2943251133 3.72131896019 3.61498594284 5.69963502884
(My computer has 4-core i3-2120 CPU @ 3.30GHz, 4G memory.
The file calculated by these program is about 2G in size.
The odd rows are about md5 and the even rows are about sha1.
The time in this table are in second.)
经过 100 多次测试,我发现 python hashlib 总是比 md5sum 或 sha1sum 快。
我还阅读了一些关于 Python2.7/Modules/{md5.c,md5.h,md5module.c} 和 gnulib lib/{md5.c,md5.h} 的源代码文档。它们都是 MD5 (RFC 1321) 的实现。
在 gnulib 中,md5 块被 32768 读取。
我对 md5 和 C 源代码了解不多。有人可以帮我解释一下这些结果吗?
我想问这个问题的另一个原因是许多人认为 md5sum 比 python_hashlib 快是理所当然的,他们更喜欢在编写 python 代码时使用 md5sum。但这似乎是错误的。
【问题讨论】:
-
那里有很多活动部件。您可能正在第二个函数中测量
POpen.communicate的性能。尝试使用time在本机 bash 中计时。 -
不是一个完整的答案:不同的实现之间通常会有性能差异,因此您不会期望 Python 和 Core Utils 的速度必然相同。但是,您的方法中缺少一些东西,例如您是否先预热缓存,以及结果的方差是多少。至于代码,只需使用
["md5sum", path]而不是shlex.split('md5sum %s' % path),因为shlex.split()和'%s %s' % (x, y)充其量只是在做相反的事情。在最坏的情况下,shlex.split()正在破坏论点。 -
谢谢。我已经删除了
shlex。没想到 Python 和 coreutils 以同样的速度实现 md5。我会阅读代码找出原因。