我目前的做法是:
def get_hash(path=PATH, hash_type='md5'):
func = getattr(hashlib, hash_type)()
with open(path, 'rb') as f:
for block in iter(lambda: f.read(1024*func.block_size, b''):
func.update(block)
return func.hexdigest()
在i5 @ 1.7 GHz上计算842MB iso文件的md5sum大约需要3.5秒。我尝试过不同的读取文件的方法,但所有这些方法都会产生较慢的结果。也许还有更快的解决方案吗?
编辑:我将2**16
(f.read()
内)替换为1024*func.block_size
,因为hashlib支持的大多数哈希函数的默认block_size
为64
(除了'sha384'和'sha512' - 对于他们来说,默认block_size
是128
)。因此,块大小仍然相同(65536位)。
编辑(3):当我再次运行该功能时,显然Windows正在使用+ 80%的磁盘。这真的需要3.5秒。呼。
另一个解决方案(〜-0.5秒,稍快)是使用os.open():
def get_hash(path=PATH, hash_type='md5'):
func = getattr(hashlib, hash_type)()
f = os.open(path, (os.O_RDWR | os.O_BINARY))
for block in iter(lambda: os.read(f, 2048*func.block_size), b''):
func.update(block)
os.close(f)
return func.hexdigest()
请注意,这些结果不是最终结果。
答案 0 :(得分:1)
使用md5
openssl工具需要2秒的874 MiB随机数据文件,我能够提高速度,如下所示。
def md5_speedcheck(path, size):
pts = time.process_time()
ats = time.time()
m = hashlib.md5()
with open(path, 'rb') as f:
b = f.read(size)
while len(b) > 0:
m.update(b)
b = f.read(size)
print("{0:.3f} s".format(time.process_time() - pts))
print("{0:.3f} s".format(time.time() - ats))
人类时间就是我上面提到的。而所有这些的处理器时间与IO阻塞的差异大致相同。
这里的关键决定因素是,缓冲区大小足以缓解磁盘延迟,但小到足以避免VM页面交换。对于我的特定机器,似乎64 KiB是最佳的。