为什么不是';哈希函数的多处理实现是否比Python中的串行实现快得多?

为什么不是';哈希函数的多处理实现是否比Python中的串行实现快得多?,python,multiprocessing,md5sum,Python,Multiprocessing,Md5sum,以该代码为例: def get_hash(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, 1024*func.block_size), b''): func.update(block) os.close(f)

以该代码为例:

def get_hash(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, 1024*func.block_size), b''):
        func.update(block)
    os.close(f)
    return func.hexdigest()
此函数返回任何文件的md5sum。假设我有一个包含30多个文件的目录,我想对每个文件运行哈希函数:

def hasher(path=some_path):
    for root, dirs, files in os.walk(path, topdown=False):
        for name in files:
            path = os.path.join(root, name)
            yield get_hash(path)
@some_timer_decorator
... some testing function here ...
测试1耗时4.6849999479541秒。

现在,正如您所看到的,当前的情况让我有机会“利用”hasher函数并添加多处理:

def hasher_parallel(path=PATH):
    p = multiprocessing.Pool(3)
    for root, dirs, files in os.walk(path, topdown=False):
        for name in files:
            full_name = os.path.join(root, name)
            yield p.apply_async(get_hash, (full_name,)).get()
@some_timer_decorator
... some other testing function here ...
test2耗时4.781000137329102秒。

输出相同。我原以为并行版本会快得多,因为大多数文件都比小。您正在将作业推出,然后等待它们完成:

在作业完成之前,这些块将一直阻塞,这样您就可以有效地按顺序运行作业

收集作业,轮询作业,直到作业完成,然后
.get()
查询结果

更好的方法是,使用
.async\u apply()
调用将所有作业推入池中,然后关闭池,调用
.join()
(在所有作业完成之前都会阻塞),然后使用
.get()
检索结果:

您可以使用简化代码;它将产生可用的结果:

def hasher_parallel(path=PATH):
    p = multiprocessing.Pool(3)
    filenames = (os.path.join(root, name)
        for root, dirs, files in os.walk(path, topdown=False)
        for name in files)
    for result in p.imap(get_hash, filenames):
        yield result
但也要尝试chunksize参数和。

您正在推出作业,然后等待它们完成:

在作业完成之前,这些块将一直阻塞,这样您就可以有效地按顺序运行作业

收集作业,轮询作业,直到作业完成,然后
.get()
查询结果

更好的方法是,使用
.async\u apply()
调用将所有作业推入池中,然后关闭池,调用
.join()
(在所有作业完成之前都会阻塞),然后使用
.get()
检索结果:

您可以使用简化代码;它将产生可用的结果:

def hasher_parallel(path=PATH):
    p = multiprocessing.Pool(3)
    filenames = (os.path.join(root, name)
        for root, dirs, files in os.walk(path, topdown=False)
        for name in files)
    for result in p.imap(get_hash, filenames):
        yield result
但也要尝试chunksize参数和。

您正在推出作业,然后等待它们完成:

在作业完成之前,这些块将一直阻塞,这样您就可以有效地按顺序运行作业

收集作业,轮询作业,直到作业完成,然后
.get()
查询结果

更好的方法是,使用
.async\u apply()
调用将所有作业推入池中,然后关闭池,调用
.join()
(在所有作业完成之前都会阻塞),然后使用
.get()
检索结果:

您可以使用简化代码;它将产生可用的结果:

def hasher_parallel(path=PATH):
    p = multiprocessing.Pool(3)
    filenames = (os.path.join(root, name)
        for root, dirs, files in os.walk(path, topdown=False)
        for name in files)
    for result in p.imap(get_hash, filenames):
        yield result
但也要尝试chunksize参数和。

您正在推出作业,然后等待它们完成:

在作业完成之前,这些块将一直阻塞,这样您就可以有效地按顺序运行作业

收集作业,轮询作业,直到作业完成,然后
.get()
查询结果

更好的方法是,使用
.async\u apply()
调用将所有作业推入池中,然后关闭池,调用
.join()
(在所有作业完成之前都会阻塞),然后使用
.get()
检索结果:

您可以使用简化代码;它将产生可用的结果:

def hasher_parallel(path=PATH):
    p = multiprocessing.Pool(3)
    filenames = (os.path.join(root, name)
        for root, dirs, files in os.walk(path, topdown=False)
        for name in files)
    for result in p.imap(get_hash, filenames):
        yield result


但是也要尝试chunksize参数和。

问题是,如果我多次运行脚本,磁盘使用率将保持在0%。只有CPU显示出活动迹象。2个内核和4个逻辑处理器。我在文档中没有看到任何
AsyncResult.read()
的使用示例,我也不完全理解您的意思。你能给我举个例子吗?这正是我想要的,但我不知道如何调用close()和join()。我还是个初学者。谢谢Martijn。就是这样,你是我的超级英雄。问题是,如果我多次运行脚本,磁盘使用率将保持在0%。只有CPU显示出活动迹象。2个内核和4个逻辑处理器。我在文档中没有看到任何
AsyncResult.read()
的使用示例,我也不完全理解您的意思。你能给我举个例子吗?这正是我想要的,但我不知道如何调用close()和join()。我还是个初学者。谢谢Martijn。就是这样,你是我的超级英雄。问题是,如果我多次运行脚本,磁盘使用率将保持在0%。只有CPU显示出活动迹象。2个内核和4个逻辑处理器。我在文档中没有看到任何
AsyncResult.read()
的使用示例,我也不完全理解您的意思。你能给我举个例子吗?这正是我想要的,但我不知道如何调用close()和join()。我还是个初学者。谢谢Martijn。就是这样,你是我的超级英雄。问题是,如果我多次运行脚本,磁盘使用率将保持在0%。只有CPU显示出活动迹象。2个内核和4个逻辑处理器。我在文档中没有看到任何
AsyncResult.read()
的使用示例,我也不完全理解您的意思。你能给我举个例子吗?这正是我想要的,但我不知道如何调用close()和join()。我还是个初学者。谢谢你,Martijn。就这样,你是我的超级英雄。顺便说一句,你为什么要调用
。应用异步()
,然后调用
。get()
?你是什么意思?我认为通过使用
.get()
我实际上可以得到结果。是的,但是
.get()
等待函数完成。在当前作业完成之前,您不会向池中添加新作业。顺便说一句,为什么要调用
。应用异步()
,然后通过调用
。get()
进行阻止?这是什么意思?我认为通过使用
.get()
我实际上可以得到结果。是的,但是
.get()
等待函数完成。在当前作业完成之前,您不会将新作业添加到池中。顺便说一句,为什么要调用
。apply_async()
,然后通过CALI阻止