没有使用gevent加速读取文件

时间:2015-07-06 11:06:49

标签: python numpy gevent

我需要使用向量加载~100k文件并将内容聚合在一个numpy数组中。这个过程需要大约3分钟,所以我想加快速度。我试图用gevent来加速它,但我无法获得任何加速。

我读到应该使用异步调用来加速IO调用而不是多处理。我进一步读到gevent是推荐的库。我写了一个下载图像的例子,在那里我可以看到速度的巨大提升。这是我的代码的简化版本

def chunks(l, n):
    """ Yield successive n-sized chunks from l.
    """
    for i in xrange(0, len(l), n):
        yield l[i:i+n]

file_paths = # list of filenames
numpy_array = numpy.ones([len(file_paths), file_size])
pool = gevent.pool.Pool(poolsize)
for i, list_file_path_tuples in enumerate(chunks(file_paths, CHUNK_SIZE)):
    gevent_results = pool.map(numpy.load, list_file_path_tuples)
    pool.join()
    for i_chunk, result in enumerate(gevent_results):
        index = i * CHUNK_SIZE + i_chunk
        data = result['arr_0']
        numpy_array[index] = data

使用块是必要的,否则我会在内存中将所有向量都包含两次。

我的代码中是否存在问题,或者我使用了错误的方法?

1 个答案:

答案 0 :(得分:4)

您是否已分析过您的代码并了解热点所在的位置?如果它不是计算,它可能只是磁盘IO。我怀疑你通过IO逻辑上的技巧来提升性能。最后,它可能是限制的顺序磁盘访问。如果你有一个RAID系统,从磁盘读取多个线程可能是有意义的,但你可以用python标准线程来做。尝试从1增加到几个并沿途测量以找到最佳位置。

您看到并行gevent下载映像的改进的原因是,通过多个连接可以大大提高网络IO吞吐量。当远程服务器未直接连接到您的网络设备时,单个网络连接很难使网络带宽饱和。而单个磁盘IO操作可以轻松地使磁盘吞吐量饱和。