2010-11-22 12 views
6

मैंने हाल ही में list(), dict(), tuple()[], {}, और () के स्थान पर क्रमशः तीनों में से एक को खाली करने की आवश्यकता के दौरान उपयोग करने में देखा है। तर्क यह है कि यह और अधिक पठनीय लग रहा था। मैं शैली पर राय मांगने जा रहा था, लेकिन फिर मैंने प्रदर्शन का परीक्षण करने का फैसला किया। मैं इस किया था:सूची(), dict(), और tuple() क्यों धीमी है [], {}, और()?

    :

    >>> from timeit import Timer 
    >>> Timer('for x in range(5): y = []').timeit() 
    0.59327821802969538 
    >>> from timeit import Timer 
    >>> Timer('for x in range(5): y = list()').timeit() 
    1.2198944904251618 
    

    मैंने कोशिश की dict(), tuple() और list() और प्रत्येक के समारोह कॉल संस्करण वाक्य-संस्करण ({}[], ()) तो से अविश्वसनीय रूप से भी बदतर था, मैं 3 प्रश्न हैं

  1. फ़ंक्शन अधिक महंगा क्यों कहता है?
  2. इतना अंतर क्यों है?
  3. मेरे टाइमर में 5 खाली सूचियां बनाने के लिए हेक में 1.2 सेकंड क्यों लगते हैं? मुझे पता है कि timeit कचरा संग्रह बंद कर देता है, लेकिन जब संभवतः मैंने केवल range(5) का उपयोग किया तो इसका प्रभाव संभव नहीं हो सका।
+0

पुन: शैली की राय - मैं अक्सर [] का उपयोग करता हूं। मुझे लगता है कि यह काफी स्पष्ट है। हालांकि प्रदर्शन सवाल दिलचस्प है। – nmichaels

+0

ऐसी कई चीजें हैं जो पाइथन के बारे में अजीब लगती हैं जब तक कि आप उनका उपयोग न करें। मैं हमेशा '[] 'से' सूची()' पसंद करता हूं क्योंकि 'सूची()' वास्तव में '__builtins __। सूची 'नहीं हो सकती है। सावधान ग्राहक। – SingleNegationElimination

उत्तर

18

फ़ंक्शन कॉल के लिए एक चर नाम नाम की आवश्यकता होती है, उसके बाद फ़ंक्शन आमंत्रण होता है। तब कहा जाता है कि फ़ंक्शन एक सूची बनाता है और इसे वापस करता है।

>>> import dis 
>>> foo = lambda :[] 
>>> bar = lambda :list() 
>>> dis.dis(foo) 
    1   0 BUILD_LIST    0 
       3 RETURN_VALUE   
>>> dis.dis(bar) 
    1   0 LOAD_GLOBAL    0 (list) 
       3 CALL_FUNCTION   0 
       6 RETURN_VALUE   
>>> 
0

स्कोप लुकअप dict, tuple, और list को खोजने के क्रम में आवश्यक है, और अनेक दायरे ताकि उन्हें खोजने के लिए खोज करने की आवश्यकता है। सिंटैक्टिक चीनी के साथ संकलक यह जान सकता है कि एक विशिष्ट वस्तु को बनाने की आवश्यकता है और इसलिए ऐसा करने के लिए उचित बाइटकोड उत्सर्जित कर सकते हैं।

+1

'[]' कुछ भी के लिए वाक्य रचनात्मक चीनी नहीं है। यह एक सूची शाब्दिक है। – SingleNegationElimination

+0

@ टोकनमैकगुय: यह वास्तव में वाक्य रचनात्मक चीनी है। सूची 'सूची() 'का आह्वान करके उत्पन्न की जा सकती है, लेकिन संकलक एक सूची बनाने के रूप में उचित संदर्भ में स्क्वायर ब्रैकेट की व्याख्या करेगा। –

+2

संकलक * [] 'मुठभेड़ करता है * सूची * (''' का आह्वान करता है जब यह '[] 'से मिलता है। मेरा जवाब देखें – SingleNegationElimination

2
>>> from dis import dis 

    >>> dis(lambda: list()) 
    1   0 LOAD_GLOBAL    0 (list) 
       3 CALL_FUNCTION   0 
       6 RETURN_VALUE   

    >>> dis(lambda: []) 
    1   0 BUILD_LIST    0 
       3 RETURN_VALUE   
5

# 3 उत्तर देने के लिए: सूची वाक्य रचना शाब्दिक सिर्फ एक सूची बनाने के लिए दुभाषिया हो जाता है।

timeit वास्तव में डिफ़ॉल्ट रूप से आपके प्रोग्राम को 1 000 000 बार दोहराता है। तो वास्तव में, आप 1.2 सेकंड में 5 मिलियन सूचियां बना रहे हैं।

+0

धन्यवाद। मुझे लगता है अगली बार मुझे आरटीएफएम चाहिए :) – orokusaki

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