我需要使用向量加载约10万个文件,并将内容汇总到一个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
使用块是必要的,因为否则我会将所有向量存储在内存中两次.
我的代码中有问题吗?还是我使用了错误的方法?
解决方法:
您是否分析了代码并知道热点在哪里?如果不进行计算,则可能只是磁盘IO.我怀疑通过IO逻辑的技巧可以提高性能.最后,顺序磁盘访问可能是限制.如果您确实有RAID系统,那么从磁盘读取多个线程可能很有意义,但是您可以使用python标准线程来做到这一点.尝试从1增加到几个,并一路测量以找到最佳位置.
看到gevent并行下载映像的原因在于,通过多个连接可以大大提高网络IO吞吐量.当远程服务器未直接连接到网络设备时,单个网络连接几乎无法饱和网络带宽.而单个磁盘IO操作可以轻松使磁盘吞吐量饱和.