imap
/ imap_unordered
와 map
/ 사이에는 두 가지 주요 차이점이 있습니다 map_async
.
- 그들이 당신이 그들에게 전달하는 iterable을 소비하는 방식.
- 그들이 당신에게 결과를 돌려주는 방법.
map
iterable을 목록으로 변환하고 (이미 목록이 아니라고 가정)이를 청크로 나누고 해당 청크를의 작업자 프로세스로 전송하여 iterable을 사용합니다 Pool
. iterable을 청크로 나누면 프로세스마다 iterable의 각 항목을 한 번에 한 항목 씩 전달하는 것보다 낫습니다 (특히 iterable이 큰 경우). 그러나 전체 목록을 메모리에 보관해야하기 때문에 이터 러블을 목록으로 변환하여 청크를 만들려면 메모리 비용이 매우 높아질 수 있습니다.
imap
반복 가능한 것을 목록으로 바꾸거나 덩어리로 나누지 않습니다 (기본적으로). 한 번에 반복 가능한 한 요소를 반복하여 각 요소를 작업자 프로세스로 보냅니다. 이것은 전체 iterable을리스트로 변환 할 때의 메모리 히트를 가져 오지 않지만, 청킹 (chunking)이 없기 때문에 큰 iterable의 경우 성능이 느려진다는 것을 의미합니다. chunksize
그러나 기본값 1보다 큰 인수 를 전달하면이를 완화 할 수 있습니다 .
사이의 주요 차이점은 imap
/ imap_unordered
과 map
/ map_async
와 있다는 것입니다 imap
/ imap_unordered
당신이 곧 오히려 완료 될 그들 모두를 기다리는 것보다, 그들이있는 거 준비 등으로 노동자로부터 결과를 수신 시작할 수 있습니다. 와 map_async
은 AsyncResult
즉시 반환하지만, 그들 모두가 처리 될 때까지 당신이 실제로하는이 같은 목록을 반환 점, 그 객체의 결과를 검색 할 수 없습니다 map
않습니다 ( map
실제로 내부적으로 구현됩니다 map_async(...).get()
). 부분적인 결과를 얻을 수있는 방법은 없습니다. 당신은 전체 결과를 얻거나 아무것도 없습니다.
imap
그리고 imap_unordered
모두 반환 즉시 반복 가능 객체. 를 사용 imap
하면 입력 iterable의 순서를 유지하면서 준비가 완료되는 즉시 iterable에서 결과가 산출됩니다. 를 사용하면 imap_unordered
반복 가능한 입력 순서에 관계없이 준비가 완료되는 즉시 결과가 산출됩니다. 따라서 이것이 있다고 가정하십시오.
import multiprocessing
import time
def func(x):
time.sleep(x)
return x + 2
if __name__ == "__main__":
p = multiprocessing.Pool()
start = time.time()
for x in p.imap(func, [1,5,3]):
print("{} (Time elapsed: {}s)".format(x, int(time.time() - start)))
출력됩니다 :
3 (Time elapsed: 1s)
7 (Time elapsed: 5s)
5 (Time elapsed: 5s)
p.imap_unordered
대신에 사용 p.imap
하면 다음이 표시됩니다.
3 (Time elapsed: 1s)
5 (Time elapsed: 3s)
7 (Time elapsed: 5s)
당신이 사용하는 경우 p.map
또는 p.map_async().get()
, 당신은 볼 수 있습니다 :
3 (Time elapsed: 5s)
7 (Time elapsed: 5s)
5 (Time elapsed: 5s)
따라서 imap
/ imap_unordered
over 를 사용하는 주요 이유 map_async
는 다음과 같습니다.
- iterable은 목록으로 변환하면 너무 많은 메모리가 부족하거나 사용됩니다.
- 모든 결과 가 완료 되기 전에 결과 처리를 시작하려고합니다 .