【问题标题】:how to efficiently traverse a directory and get the sha256 checksum for each file如何有效地遍历目录并获取每个文件的 sha256 校验和
【发布时间】:2014-11-28 11:13:55
【问题描述】:

我想遍历任何目录并可以计算每个文件的checkusum,目前我正在使用python multiprocessing和以下代码:

import hashlib
import os
import time

from multiprocessing import Pool


def list_files(path):
    directories = []
    files = []

    def append_files(x):
        files.append(x)

    pool = Pool()

    src = os.path.abspath(os.path.expanduser(path))
    for root, dirs_o, files_o in os.walk(src):
        for name in dirs_o:
            directories.append(os.path.join(root, name))
        for name in files_o:
            file_path = os.path.join(root, name)
            if os.path.isfile(file_path):
                pool.apply_async(
                    sha256_for_file,
                    args=(file_path,),
                    callback=append_files)

    pool.close()
    pool.join()

    return directories, files

def sha256_for_file(path, block_size=4096):
    try:
        with open(path, 'rb') as rf:
            h = hashlib.sha256()
            for chunk in iter(lambda: rf.read(block_size), b''):
                h.update(chunk)
        return h.hexdigest(), path
    except IOError:
        return None, path

if __name__ == '__main__':
    start_time = time.time()

    d, f = list_files('~')
    print len(f)

    print '\n' + 'Elapsed time: ' + str(time.time() - start_time)      

代码使用python apply_async,我尝试使用mapmap_async,但在速度方面没有看到任何改进,我也尝试了ThreadPool,但变得更慢了。

from multiprocessing.pool import ThreadPool

pool = TreadPool()
...

关于如何优化或改进代码以便可用于遍历巨大目录并使用 python 2.7 计算每个文件的校验和的任何想法?

在 MacBook Pro(3GHz Intel Core i7、16 GB RAM 1600 MHz DDR3、SSD 磁盘)上计算用户主目录“~”中所有文件 (215658) 的哈希值:194.71100688 秒。

【问题讨论】:

  • 对我来说,这个代码是最快的,池中只有 2 个进程(它会使用来自 os.cpu_count() 的 8 个进程)。

标签: python multithreading python-2.7 multiprocessing checksum


【解决方案1】:

让我们仔细看看多线程部分。你的程序是做什么的?

  1. 遍历目录
  2. 打开文件并计算其校验和

12 需要并发磁盘访问,而只有 2 执行实际计算。由于此并发磁盘访问,对步骤 12 使用不同的线程不会提高速度。但是 2 可以分为两个不同的步骤:

  1. 遍历目录
  2. 打开文件并读取其内容
  3. 计算内容校验和

12 可以属于一个线程(磁盘访问,写入内存),而 3 可以在单独的线程中执行(读内存,CPU计算)。

不过,我不确定您是否会获得巨大的性能提升,因为哈希计算通常不是 CPU 密集型的:大部分计算时间可能用于磁盘读取...

【讨论】:

  • 关于如何执行第 2 步和第 3 步、如何在一个线程中读取和存储内容(可能使用队列)以及其他计算校验和的任何想法?我认为在处理大文件时这可能会成为问题。
  • Queue 听起来确实是实现它的好方法。 docs.python.org/2/library/queue.html 显示的示例与您的问题非常相似!
【解决方案2】:

尝试测量函数 sha256_for_file 的集体执行时间。

如果接近 190 秒,那么这是您应该优化或并行化的一段代码(在一个线程中读取块,在第二个线程中计算)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-11-23
    • 2013-09-22
    • 1970-01-01
    • 2011-12-29
    • 2015-12-30
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多