Havuz: map_async ve imap arasındaki fark nedir?


184

Python'ın kullanmayı öğrenmek çalışıyorum multiprocessingpaketi, ama ben arasındaki farkı anlayamıyorum map_asyncve imap. Ben fark olduğunu hem map_asyncve imapasenkron olarak yürütülür. Peki birini ne zaman diğerinin üzerine kullanmalıyım? Ve döndürülen sonucu nasıl almalıyım map_async?

Böyle bir şey kullanmalı mıyım?

def test():
    result = pool.map_async()
    pool.close()
    pool.join()
    return result.get()

result=test()
for i in result:
    print i

Yanıtlar:


493

imap/ imap_unorderedVe map/ arasında iki temel fark vardır map_async:

  1. Onlara geçtiğiniz itibari tüketme biçimleri.
  2. Sonucu size geri döndürme şekilleri.

mapyinelemeyi bir listeye dönüştürerek (zaten bir liste olmadığı varsayılarak), parçaları parçalara bölerek ve bu parçaları içindeki işçi işlemlerine göndererek yinelenebilir Pool. Yinelenebilir öğelerin parçalara bölünmesi, her öğeyi yinelenen işlemler arasında, her seferinde bir öğe olmak üzere, özellikle de yinelenebilir büyükse, daha iyi performans gösterir. Bununla birlikte, parçalanabilmesi için tekrarlanabilir bir listeye dönüştürülmesi çok yüksek bir bellek maliyetine sahip olabilir, çünkü tüm listenin bellekte tutulması gerekecektir.

imapverdiğiniz yinelemeyi bir listeye dönüştürmez ya da parçalara ayırmaz (varsayılan olarak). Teker teker yinelenebilir bir öğe üzerinde yinelenecek ve her birini bir çalışan işlemine gönderecektir. Bu, tüm yinelenebilir bir listeyi dönüştürmek için bellek isabet almazsınız, ama aynı zamanda, parçalanma eksikliği nedeniyle performansın büyük yinelenebilirler için daha yavaş olduğu anlamına gelir. Ancak bu, chunksizevarsayılan değer olan 1'den daha büyük bir argüman iletilerek hafifletilebilir .

Arasındaki diğer önemli fark imap/ imap_unorderedve map/ map_asyncile yani imap/ imap_unordered, yakında oldukça bitirilmesi hepsi için beklemek zorunda daha, onlar hazır olduğunca işçilerden sonuçları almaya başlayabilirsiniz. İle map_async, AsyncResulthemen döndürülür, ancak hepsi işlenene kadar o nesneden sonuçları alamazsınız, bu noktalarda aynı listeyi döndürür map( mapaslında dahili olarak uygulanmaktadır map_async(...).get()). Kısmi sonuçlar almanın bir yolu yoktur; ya tüm sonuca sahipsiniz ya da hiçbir şey.

imapve imap_unorderedher ikisi de hemen tekrarlanabilir. İle imap, sonuçlar hazır olur olmaz yinelemeden elde edilirken, yine de girdinin sıralanabilirliğini korurken elde edilir. İle imap_unordered, sonuçlar, tekrarlanabilir girdinin sırasına bakılmaksızın hazır olur olmaz verilecektir. Yani, diyelim ki:

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)))

Bu çıktı:

3 (Time elapsed: 1s)
7 (Time elapsed: 5s)
5 (Time elapsed: 5s)

p.imap_unorderedBunun yerine kullanırsanız p.imapşunları görürsünüz:

3 (Time elapsed: 1s)
5 (Time elapsed: 3s)
7 (Time elapsed: 5s)

p.mapVeya kullanırsanız p.map_async().get()şunları görürsünüz:

3 (Time elapsed: 5s)
7 (Time elapsed: 5s)
5 (Time elapsed: 5s)

Bu nedenle, imap/ imap_unorderedover kullanmanın başlıca nedenleri map_async:

  1. Yinelemeniz, bir listeye dönüştürmenizde çok fazla bellek kalmaması / kullanılmasına neden olacak kadar büyüktür.
  2. Sen önce sonuçları işlemeye başlamak için mümkün istiyorum tüm bunlardan tamamlanır.

1
Apply ve camera_async ne olacak?
Sert Daftary

10
@ HarshDaftary, applybir alt işleme tek bir görev gönderir ve tamamlanıncaya kadar engeller. apply_asyncbir çalışma sürecine tek bir görev gönderir ve hemen AsyncResultgörevin bitmesini ve sonucun alınmasını beklemek için kullanılabilecek bir nesne döndürür . applysadece arayarak uygulanırapply_async(...).get()
dano

52
Bu , mevcut donukPool olandan ziyade resmi belgelerde olması gereken türden açıklamalar .
dakika

@dano Arka planda bir işlev çalıştırmak istiyorum, ancak bazı kaynak kısıtlamaları var ve işlevi istediğim kadar çok çalıştıramaz ve işlevin fazladan yürütmelerini sıraya koyamazsınız. Bunu nasıl yapmam gerektiğine dair bir fikrin var mı? Benim sorum burada . Lütfen soruma bir göz atabilir ve bana bunu nasıl yapmam gerektiğine dair bazı ipuçları (ya da daha iyisi, bir cevap) verebilir misiniz?
Amir

1
@BallpointBen İşlem biter bitmez bir sonraki iş parçasına geçecektir. Sipariş, ana süreçte geri alınır.
dano
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.