![](/img/trans.png)
[英]What's the best way to divide large files in Python for multiprocessing?
[英]Best way to perform multiprocessing on a large file Python
我有一個python腳本,它將遍歷一個列表(> 1000個元素),在一個大文件中找到變量,然后輸出結果。 我正在讀取整個文件> 1000次。 我嘗試使用多處理,但沒有太大幫助。 這是我想做的事情:
import gzip
from multiprocessing.pool import ThreadPool as Pool
def getForwardIP(clientIP, requestID):
with gzip.open("xyz.log") as infile:
for lines in infile:
line= lines.split(" ")
myRequestID= line[0]
forwardIP= line[1]
if myRequestID==requestID:
print forwardIP
if __name__== "__main__":
pool_size=8
pool= Pool(pool_size)
request_id_list= list()
#request_id_list contains >1000 elements
for id in request_id_list:
pool.apply_async(getForwardIP, ("1.2.3.4.", id, ))
pool.close()
pool.join()
有沒有更快的方法? 任何幫助將不勝感激。 謝謝!
編輯
(我在這里輸入我的完整代碼)謝謝大家的建議。 現在,我將文件寫入列表,而不是讀取1000次。 我試圖對for循環進行多進程處理,但沒有成功。 下面是代碼:
import gzip
import datetime
from multiprocessing.pool import ThreadPool as Pool
def getRequestID(r_line_filename):
requestIDList= list()
with gzip.open(r_line_filename) as infile:
#r_line_filename is a file with request_id and client_ip
for lines in infile:
line= lines.split(" ")
requestID= line[1].strip("\n")
myclientIP= line[0]
if myclientIP==clientIP:
requestIDList.append(requestID)
print "R line List Ready!"
return(requestIDList)
def getFLineList(fFilename):
fLineList= list()
with gzip.open(fFilename) as infile:
#fFilename is a file with format request_id, forward_ip, epoch time
for lines in infile:
fLineList.append(lines.split())
print "F line list ready!"
return(fLineList)
def forwardIP(lines, requestID):
myrequestID= lines[0]
forwardIP= lines[1]
epoch= int(lines[2].split(".")[0])
timex= datetime.datetime.fromtimestamp(epoch).strftime('%Y-%m-%d %H:%M:%S')
if myrequestID==requestID:
print "%s %s %s"%(clientIP, timex, forwardIP)
if __name__== "__main__":
pool= Pool()
clientIP= "x.y.z.a"
rLineList= getRequestID("rLine_subset.log.gz")
fLineList= getFLineList("fLine_subset.log.gz")
for RID in rLineList:
for lines in fLineList:
pool.apply_async(forwardIP, (lines, RID,))
pool.close()
pool.join()
多處理部分無法正常工作。 實際上,這一步要慢得多。 如果我不進行多重處理而只是遍歷列表,則速度會更快。 謝謝您的幫助!
我同意mwm314,您不應將文件讀取1000次。
我假設您沒有提供完整的代碼,因為client_ip
參數似乎尚未使用,但是在這里,我將其重寫為僅打開文件一次,並且僅迭代文件中的每一行。 我還修改了getForwardIP
以獲取請求ID的列表,並立即將其轉換為一組以獲得最佳查找性能。
import gzip
def getForwardIP(client_ip, request_ids):
request_ids = set(request_ids) # to get O(1) lookup
with gzip.open("xyz.log") as infile:
for lines in infile:
line = lines.split(" ")
found_request_id = line[0]
found_forward_ip = line[1]
if found_request_id in request_ids:
print found_forward_ip
if __name__ == "__main__":
request_id_list = list()
# request_id_list contains >1000 elements
getForwardIP("1.2.3.4.", request_id_list)
確實有更快的方法。 不要在1000次內讀取和解析文件。 而是一次讀一次,解析一次,然后存儲。 文件I / O是您可以執行的最慢的操作之一(使用任何語言)。 在內存中處理要快得多!
像這樣的東西(因為我沒有訪問"xyz.log"
未經測試。)對於鷹派:很明顯,我也沒有配置它,但是我有一個偷偷摸摸的懷疑,一次讀取文件比讀取文件快1000次):
import gzip
def readFile():
my_lines = []
with gzip.open("xyz.log") as infile:
for lines in infile:
line = lines.split(" ")
my_lines.append(line)
return my_lines
def getForwardIp(lines, requestID): #Doesn't look like you need client IP (yet), so I nuked it
myRequestID= line[0]
forwardIP= line[1]
if myRequestID==requestID:
print forwardIP
if __name__ == "__main__":
parsed_lines = readFile()
request_id_list= list()
#request_id_list contains >1000 elements
for id in request_id_list:
getForwardIp(parsed_lines, requestID)
我可能會在單個大文件中掃描所有請求的ID,然后充分利用ThreadPool
調用getForwardIP()
。
您可以將單個大文件划分為多個區域,並讓多個工作進程處理文件的不同分區,但是這種方法存在一些挑戰,可能無法在所有文件系統上使用。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.