我的代码中有一个函数应该读取文件。每个文件大约是8M,但读取速度太低,为了改善我使用multiprocessing.sadly,它似乎被阻止了。我想知道有什么方法可以帮助解决这个问题并提高阅读速度吗?
我的代码如下:
import multiprocessing as mp
import json
import os
def gainOneFile(filename):
file_from = open(filename)
json_str = file_from.read()
temp = json.loads(json_str)
print "load:",filename," len ",len(temp)
file_from.close()
return temp
def gainSortedArr(path):
arr = []
pool = mp.Pool(4)
for i in xrange(1,40):
abs_from_filename = os.path.join(path, "outputDict"+str(i))
result = pool.apply_async(gainOneFile,(abs_from_filename,))
arr.append(result.get())
pool.close()
pool.join()
arr = sorted(arr,key = lambda dic:len(dic))
return arr
和通话功能:
whole_arr = gainSortedArr("sortKeyOut/")
答案 0 :(得分:4)
你有一些问题。首先,你没有并行化。你这样做:
result = pool.apply_async(gainOneFile,(abs_from_filename,))
arr.append(result.get())
一遍又一遍地调度任务,然后立即调用.get()
等待它完成任务,然后再发送任何其他任务;你实际上从未有过一个以上的工人。存储所有结果而不调用.get()
,然后再调用.get()
。或者只使用Pool.map
或相关方法,并从手动个人结果管理中省去一些麻烦,例如: (使用imap_unordered
来最小化开销,因为您只是进行排序):
# Make generator of paths to load
paths = (os.path.join(path, "outputDict"+str(i)) for i in xrange(1, 40))
# Load them all in parallel, and sort the results by length (lambda is redundant)
arr = sorted(pool.imap_unordered(gainOneFile, paths), key=len)
其次,multiprocessing
必须pickle和unpickle所有参数并返回主进程和worker之间发送的值,并且所有这些都是通过管道发送的,这会引起系统调用开销。由于您的文件系统不太可能通过并行读取获得大幅度的速度,因此可能是净损失,而不是增益。
你可能可以通过切换到基于线程的池来获得一点提升;将import
更改为import multiprocessing.dummy as mp
,您将获得以线程形式实现的Pool
版本;它们不能围绕CPython GIL工作,但由于这个代码几乎肯定是I / O绑定的,这几乎不重要,它消除了酸洗和去除以及工作者通信中涉及的IPC。
最后,如果您在类似UNIX的系统上使用Python 3.3或更高版本,您可以通过让文件更积极地将文件拉入系统缓存来帮助您。如果您可以打开该文件,则使用文件描述符.fileno()
对文件对象WILLNEED
使用SEQUENTIAL
,$linkData = [
// 'link' => 'http://www.example.com',
'message' => 'User provided message',
'source' => $fb->fileToUpload('/img/about_two.jpg'),
];
try {
// Returns a `Facebook\FacebookResponse` object
$response = $fb->post('/me/photos', $linkData, 'XXXXXXXXXXX');
} catch(Facebook\Exceptions\FacebookResponseException $e) {
echo 'Graph returned an error: ' . $e->getMessage();
exit;
} catch(Facebook\Exceptions\FacebookSDKException $e) {
echo 'Facebook SDK returned an error: ' . $e->getMessage();
exit;
}
或<h1 class="h1name" style="" ><bold><%= @user %></bold><span class="glyphicon glyphicon-pencil" aria-hidden="true"></span></h1>
可能通过在请求之前积极预取文件数据,在稍后读取文件时提高读取性能。