【发布时间】:2019-06-20 12:25:45
【问题描述】:
我正在尝试计算文件的哈希值以检查是否进行了任何更改。 我有 Gui 和其他一些观察者在事件循环中运行。 所以,我决定异步计算文件的哈希值 [md5/Sha1 哪个更快]。
同步码:
import hashlib
import time
chunk_size = 4 * 1024
def getHash(filename):
md5_hash = hashlib.md5()
with open(filename, "rb") as f:
for byte_block in iter(lambda: f.read(chunk_size), b""):
md5_hash.update(byte_block)
print("getHash : " + md5_hash.hexdigest())
start = time.time()
getHash("C:\\Users\\xxx\\video1.mkv")
getHash("C:\\Users\\xxx\\video2.mkv")
getHash("C:\\Users\\xxx\\video3.mkv")
end = time.time()
print(end - start)
同步代码输出:2.4000535011291504
异步代码:
import hashlib
import aiofiles
import asyncio
import time
chunk_size = 4 * 1024
async def get_hash_async(file_path: str):
async with aiofiles.open(file_path, "rb") as fd:
md5_hash = hashlib.md5()
while True:
chunk = await fd.read(chunk_size)
if not chunk:
break
md5_hash.update(chunk)
print("get_hash_async : " + md5_hash.hexdigest())
async def check():
start = time.time()
t1 = get_hash_async("C:\\Users\\xxx\\video1.mkv")
t2 = get_hash_async("C:\\Users\\xxx\\video2.mkv")
t3 = get_hash_async("C:\\Users\\xxx\\video3.mkv")
await asyncio.gather(t1,t2,t3)
end = time.time()
print(end - start)
loop = asyncio.get_event_loop()
loop.run_until_complete(check())
异步代码输出:27.957366943359375
我做得对吗?或者,是否需要进行任何更改以提高代码的性能?
提前致谢。
【问题讨论】:
-
根据物理设备,它们并行读取大文件可能比一个接一个地读取它们要慢得多,因为它需要查找时间。
-
@KlausD。是的,我玩过更改块大小的代码,并发现异步代码越大块大小越快,它与同步代码没有任何区别。
-
更好地使用线程。现在您正在使用隐藏在
async/await后面的线程池。直接使用concurrent.futures.ThreadPoolExecutor。 -
使用
time.process_time(),您可能会获得更有意义的时光。 -
@BlackJack 是的,使用线程不会中断事件循环。但我从少数消息来源听说,在异步编程方法中避免使用线程是最佳实践。由于异步编程的主要目的是避免为处理创建线程。
标签: python hash python-asyncio python-aiofiles