2011-06-02 15 views
6

के प्रदर्शन और मान लीजिए आप अजगर में एक सूची समझ मिल गया है च बिना किसी दुष्प्रभाव सिर्फ एक समारोह होने जैसाअजगर सूची comprehensions

Values = [ f(x) for x in range(0, 1000) ] 
साथ

,। तो सभी प्रविष्टियों को स्वतंत्र रूप से गणना की जा सकती है।

क्या पाइथन "स्पष्ट" कार्यान्वयन की तुलना में इस सूची की समझ के प्रदर्शन को बढ़ाने में सक्षम है; जैसे मल्टीकोर सीपीयू पर साझा-स्मृति-समांतरता द्वारा?

+0

मुझे नहीं लगता कि अजगर कर सकते हैं, लेकिन वहाँ एक ऐसी ही सवाल में कुछ और जानकारी है http://stackoverflow.com/questions/ इस उदाहरण पर विचार 5236364/कैसे करने वाली parallelize-सूची-समझ-गणना में अजगर। –

उत्तर

7

पायथन 3.2 में उन्होंने concurrent.futures जोड़ा, समस्याओं को हल करने के लिए एक अच्छी लाइब्रेरी समवर्ती।

import math, time 
from concurrent import futures 

PRIMES = [112272535095293, 112582705942171, 112272535095293, 115280095190773, 115797848077099, 1099726899285419, 112272535095293, 112582705942171, 112272535095293, 115280095190773, 115797848077099, 1099726899285419] 

def is_prime(n): 
    if n % 2 == 0: 
     return False 

    sqrt_n = int(math.floor(math.sqrt(n))) 
    for i in range(3, sqrt_n + 1, 2): 
     if n % i == 0: 
      return False 
    return True 

def bench(f): 
    start = time.time() 
    f() 
    elapsed = time.time() - start 
    print("Completed in {} seconds".format(elapsed)) 

def concurrent(): 
    with futures.ProcessPoolExecutor() as executor: 
     values = list(executor.map(is_prime, PRIMES)) 

def listcomp(): 
    values = [is_prime(x) for x in PRIMES] 
मेरी क्वाड-कोर पर

परिणाम::

>>> bench(listcomp) 
Completed in 14.463825941085815 seconds 
>>> bench(concurrent) 
Completed in 3.818351984024048 seconds 
+1

को इंगित करने के लिए +1 आप शायद अपने "बेंच" फ़ंक्शन के लिए सजावट का उपयोग करना चाहें, क्योंकि यह वास्तव में एक सजावटी है। –

1

मैं इस परिदृश्य में map() पसंद करेंगे:

% python -m timeit ' 
f = lambda x: 2 * x 
Values = [ f(x) for x in range(0, 1000) ] 
' 
1000 loops, best of 3: 263 usec per loop 

वहाँ कोई वास्तविक प्रदर्शन लाभ हालांकि:

% python -m timeit ' 
f = lambda x: 2 * x 
Values = map(f, range(0, 1000)) 
' 
1000 loops, best of 3: 255 usec per loop 
7

नहीं है, अजगर जादुई यह आपके लिए parallelize नहीं होंगे। वास्तव में, यह नहीं कर सकता, क्योंकि यह प्रविष्टियों की आजादी साबित नहीं कर सकता है; जिसके लिए कार्यक्रम निरीक्षण/सत्यापन का एक बड़ा सौदा होगा, जो सामान्य मामले में सही होना असंभव है।

आप जल्दी मोटे सुक्ष्म मल्टीकोर समानांतरवाद चाहते हैं, मैं joblib बजाय सलाह देते हैं:

from joblib import delayed, Parallel 
values = Parallel(n_jobs=NUM_CPUS)(delayed(f)(x) for x in range(1000)) 

इतना ही नहीं मैं इस लाइब्रेरी का उपयोग कर, यह भी इस तरह के रूप संकेतों के महान सुविधा है पास रेखीय speedups देखा है Ctrl-C से इसकी कार्यकर्ता प्रक्रियाओं में से एक, जिसे सभी मल्टीप्रोसेस पुस्तकालयों के बारे में नहीं कहा जा सकता है।

ध्यान दें कि joblib नहीं वास्तव में समर्थन शेयर्ड मेमोरी समानांतरवाद: यह कार्यकर्ता प्रक्रियाओं, नहीं धागे spawns, तो यह श्रमिकों के लिए डेटा भेजने से कुछ संचार भूमि के ऊपर पड़ता है और मास्टर प्रक्रिया को वापस परिणाम है।

+2

जॉबलिब – lafras

1

यदि निम्न हो सकता है की कोशिश करो तेजी:

Values = map(f,range(0,1000)) 

कोड के लिए एक functionnal ढंग

एक और विचार जनरेटर अभिव्यक्ति द्वारा कोड में मान के सभी आवृत्तियां को बदलने के लिए है कि

imap(f,range(0,1000)) # Python < 3 

map(f,range(0,1000)) # Python 3 
संबंधित मुद्दे