2016-08-01 3 views
0

문자열 목록이 있으며 모든 문자열에 wordify()에서 볼 수있는 몇 가지 변경 사항을 수행 중입니다. 이제이를 가속화하기 위해 목록을 하위 목록으로 분할하여 chunked() (하위 목록의 수는 CPU 코어 수 -1입니다)을 사용했습니다. 그렇게하면 [[,,],[,,],[,,],[,,]]과 같은 목록을 얻을 수 있습니다.지도를 사용한 다중 처리

나는 달성하려고 무엇 :

내가 동시에 이러한 하위 목록의 모든에 wordify()을 수행 할 별도의 목록으로 하위 목록을 반환. 모든 프로세스가 완료 될 때까지 기다렸다가이 하위 목록을 하나의 목록으로 결합하려고합니다. 아래 접근법은 효과가 없습니다.

import multiprocessing 
from multiprocessing import Pool 
from contextlib import closing 

def readFiles(): 
    words = [] 
    with open("somefile.txt") as f: 
     w = f.readlines() 
    words = words + w 
    return words 


def chunked(words, num_cpu): 
    avg = len(words)/float(num_cpu) 
    out = [] 
    last = 0.0  
    while last < len(words): 
     out.append(words[int(last):int(last + avg)]) 
     last += avg  
    return out  


def wordify(chunk,wl): 
    wl.append([chunk[word].split(",", 1)[0] for word in range(len(chunk))]) 
    return wl 


if __name__ == '__main__': 
    num_cpu = multiprocessing.cpu_count() - 1 
    words = readFiles() 
    chunked = chunked(words, num_cpu) 
    wordlist = [] 
    wordify(words, wordlist) # works 
    with closing(Pool(processes = num_cpu)) as p: 
     p.map(wordify, chunked, wordlist) # fails 

답변

1

코드를 작성하여 단일 기능을 map에 전달하면됩니다. 당신의 함수의 두 번째 인수에 wordlist이 전달되기를 바란다는 것을 아는 것은 충분히 똑똑하지 않습니다.

TBH 일부 기능이 응용 프로그램은 파이썬에서 조금 투박하지만 functools.partial 사용할 수 있습니다

from functools import partial 
p.map(partial(wordify, wordlist), chunked) 
+0

첫 번째 솔루션이 나 있습니다 : 'cPickle.PicklingError을 : <유형 '기능을'> 피클 수 없습니다 : 속성 lookup __builtin __. function failed' 두 번째 솔루션은 작동하지만 느린 속도입니다 singlethreaded : 'singlethreaded : 0.423000097275','multithreaded : 0.605999946594' – doc

+0

수행중인 작업이 많은 경우가 아니라면 속도 향상을 기대할 수 없습니다. 첫 번째 쉼표로 줄을 분할하는 것은 거의 작업이 아니며 프로세스 간 파이프를 통해 문자열을 앞뒤로 보내는 것이 거의 확실합니다. 후자가 현저히 비싸지는 않습니다. 문자열을 사용하는 것이 매우 저렴합니다. –

+0

이것이 수행 될 데이터의 양이 크게 증가합니다. 하위 목록을 수정하는 동안 프로세스간에 문자열을 보낼 필요가 전혀 없기 때문에이 방법을 사용하는 것이 더 효율적입니다. 항목은 하위 목록에 다시 참여할 때 앞뒤로 보내야합니다. – doc