为什么python hashlib.md5比linux coreutils md5sum更快

时间:2014-03-25 03:04:05

标签: python md5

我刚发现python hashlib.md5可能比coreutils md5sum更快。

python hashlib

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的cal时间,读取 1048576 块。

第3列是python hashlib md5或sha1的cal时间,读取 32768 块。

第4列是python hashlib md5或sha1的cal时间,读取 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。但这似乎不对。

2 个答案:

答案 0 :(得分:2)

coreutils拥有自己的C实现,而python使用体系结构特定的程序集实现调用libcrypto。 sha1的差异更大。 现在已经修复了coreutils-8.22(当配置--with-openssl时),并在Fedora 21,RHEL 7和Arch等新版本中启用。

注意调用命令即使在某些系统上当前较慢也是一个更好的长期策略,因为可以利用封装在单独命令中的所有逻辑,而不是重新实现。例如,在coreutils中,存在对改进的稀疏文件读取的支持,以便不从内核中冗余地读取零。如果可能的话,更好地利用它。

答案 1 :(得分:1)

我不确定你是如何对此进行计时的,但差异很可能是因为您花费时间来启动子流程(考虑shlex.split的解析时间)每次拨打shell_hash