2014-10-26 7 views
6

यह ज्यादातर पायथन सीखने में एक अभ्यास है।किसी भी प्रदर्शन()

def p1(n): 
    for d in xrange(2, int(math.sqrt(n)) + 1): 
     if n % d == 0: 
      return False 
    return True 

तब मुझे एहसास हुआ कि मैं आसानी से कर सकते हैं किसी भी() का उपयोग कर इसे फिर से लिखने:

def p2(n): 
    return not any((n % d == 0) for d in xrange(2, int(math.sqrt(n)) + 1)) 

अभिनय की दृष्टि से, मैं p2 उम्मीद कर रहा था होना करने के लिए मैं अगर एक नंबर प्रधानमंत्री है परीक्षण करने के लिए इस समारोह में लिखा था की तुलना में, या बहुत कम से कम के रूप में तेजी से के रूप में तेजी से, p1 क्योंकि किसी भी() में निर्मित है, लेकिन एक बड़े ish प्रधानमंत्री के लिए, p2 काफ़ी धीमी है:

$ python -m timeit -n 100000 -s "import test" "test.p1(999983)" 
100000 loops, best of 3: 60.2 usec per loop 

$ python -m timeit -n 100000 -s "import test" "test.p2(999983)" 
100000 loops, best of 3: 88.1 usec per loop 

मैं किसी भी (का उपयोग कर रहा है) ठीक से यहाँ ? क्या इस फ़ंक्शन को किसी भी() का उपयोग करके लिखने का कोई तरीका है ताकि यह खुद को पुन: सक्रिय कर सके?

अद्यतन: और भी अधिक बड़ा प्रधानमंत्री

$ python -m timeit -n 1000 -s "import test" "test.p1(9999999999971)" 
1000 loops, best of 3: 181 msec per loop 

$ python -m timeit -n 1000 -s "import test" "test.p2(9999999999971)" 
1000 loops, best of 3: 261 msec per loop 
+0

https://docs.python.org/2/library/functions.html#any देखें जो आपने लिखा है उतना ही दिखता है। – njzk2

+1

@ rightføld एक 50% की वृद्धि एक छोटा सा अंतर है? – Barmar

+0

नहीं, लेकिन <1000 पुनरावृत्तियों की एक छोटी संख्या है कि कुछ अतिरिक्त स्टैक फ्रेम (उस समय आपके कंप्यूटर में कहीं और होने वाली सामग्री का उल्लेख नहीं करना) लूप के शरीर की तुलना में अभी भी महत्वपूर्ण हैं। –

उत्तर

4

प्रदर्शन अंतर कम है, लेकिन कारण यह मौजूद है कि any एक जनरेटर अभिव्यक्ति के निर्माण पड़ता है, और एक अतिरिक्त समारोह कॉल, पाश लिए की तुलना में के लिए नंबर । दोनों के समान व्यवहार हैं, हालांकि (शॉर्टकट मूल्यांकन)।

आपके इनपुट के आकार में वृद्धि होने के कारण, अंतर कम नहीं होगा (मैं गलत था) क्योंकि आप जनरेटर अभिव्यक्ति का उपयोग कर रहे हैं, और इसके ऊपर पुनरावृत्ति करने के लिए एक विधि (.next()) पर कॉल करना और एक अतिरिक्त स्टैक फ्रेम । any हूड के तहत, निश्चित रूप से करता है।

फॉर लूप xrange ऑब्जेक्ट पर फिर से चल रहा है। any जनरेटर अभिव्यक्ति पर पुनरावृत्ति कर रहा है, जो स्वयं xrange ऑब्जेक्ट पर फिर से चल रहा है।

किसी भी तरह से, जो भी सबसे अधिक पठनीय/रखरखाव कोड उत्पन्न करता है उसका उपयोग करें। दूसरे पर एक का चयन करने से आपके पास जो भी प्रोग्राम लिख रहा है उस पर प्रदर्शन प्रभाव कम होगा, यदि कोई हो।

+0

धन्यवाद। मैं समझता हूं कि उनके समान व्यवहार हैं, बस अंतर्निहित कार्यों के सही उपयोग को सीखने की कोशिश कर रहे हैं क्योंकि मैं पाइथन के लिए नया हूं। लेकिन मुझे अंतर भी बड़ा प्राइम के लिए कम नहीं दिख रहा है (मैं थोड़ा सा सवाल अपडेट करूंगा)। 13 अंकों के प्राइम के लिए भी, अंतर अभी भी लगभग 50% (~ 180ms बनाम ~ 270ms) है। मुझे पठनीयता के बारे में आपका मुद्दा मिलता है, लेकिन इस विशेष अभ्यास के लिए, मैं किसी भी() के उपयोग को समझने में अधिक रुचि रखता हूं। – linus

+0

धन्यवाद। यह समझ आता है। मैं इस बारे में असहमत हूं कि इसका कोई प्रदर्शन प्रभाव नहीं है। एक कार्यान्वयन दूसरे की तुलना में लगातार 50% धीमी प्रतीत होता है, इसलिए इस समारोह को कितनी बार कहा जाता है, इस पर निर्भर करता है कि एक महत्वपूर्ण अंतर भिन्नता हो सकती है। उस ने कहा, जनरेटर अभिव्यक्ति के बारे में आपका मुद्दा मुझे पूर्ण समझ में आता है। धन्यवाद! – linus

+0

ठीक है, सामान्य रूप से, काम, पठनीय कोड, * फिर * प्रोफाइल और अनुकूलित लिखें। हमेशा उस क्रम में;) –

संबंधित मुद्दे