为什么同时读取多个文件比顺序读取要慢?


问题内容

我正在尝试解析目录中找到的许多文件,但是使用多重处理会使我的程序变慢。

# Calling my parsing function from Client.
L = getParsedFiles('/home/tony/Lab/slicedFiles') <--- 1000 .txt files found here.
                                                       combined ~100MB

遵循python文档中的以下示例:

from multiprocessing import Pool

def f(x):
    return x*x

if __name__ == '__main__':
    p = Pool(5)
    print(p.map(f, [1, 2, 3]))

我已经编写了这段代码:

from multiprocessing import Pool
from api.ttypes import *

import gc
import os

def _parse(pathToFile):
    myList = []
    with open(pathToFile) as f:
        for line in f:
            s = line.split()
            x, y = [int(v) for v in s]
            obj = CoresetPoint(x, y)
            gc.disable()
            myList.append(obj)
            gc.enable()
    return Points(myList)

def getParsedFiles(pathToFile):
    myList = []
    p = Pool(2)
    for filename in os.listdir(pathToFile):
        if filename.endswith(".txt"):
            myList.append(filename)
    return p.map(_pars, , myList)

我按照该示例进行操作,将所有以a结尾的文件名放在.txt列表中,然后创建了Pools,并将它们映射到我的函数中。然后,我想返回一个对象列表。每个对象都保存文件的已解析数据。但是令我惊讶的是,我得到了以下结果:

#Pool 32  ---> ~162(s)
#Pool 16 ---> ~150(s)
#Pool 12 ---> ~142(s)
#Pool 2 ---> ~130(s)

图形:
在此处输入图片说明

机器规格:

62.8 GiB RAM
Intel® Core™ i7-6850K CPU @ 3.60GHz × 12

我在这里想念什么?
提前致谢!


问题答案:

看起来您受I / O约束

在计算机科学中,I /
O绑定是指一种条件,其中完成计算所需的时间主要由等待输入/输出操作完成所花费的时间来确定。这与受CPU约束的任务相反。当请求数据的速率比消耗数据的速率慢,或者换句话说,请求数据花费的时间多于处理数据的时间时,就会出现这种情况。

您可能需要让主线程进行读取,并在子进程可用时将数据添加到池中。这与使用有所不同map

当您一次处理一行并且输入被拆分时,您可以
fileinput

用来遍历多个文件的行,并映射到函数处理行而不是文件:

一次传递一行可能太慢,因此我们可以要求map传递块,并可以进行调整,直到找到最佳点为止。我们的函数解析了几行:

def _parse_coreset_points(lines):
    return Points([_parse_coreset_point(line) for line in lines])

def _parse_coreset_point(line):
    s = line.split()
    x, y = [int(v) for v in s]
    return CoresetPoint(x, y)

而我们的主要功能是:

import fileinput

def getParsedFiles(directory):
    pool = Pool(2)

    txts = [filename for filename in os.listdir(directory):
            if filename.endswith(".txt")]

    return pool.imap(_parse_coreset_points, fileinput.input(txts), chunksize=100)