2010-03-09 15 views
9

मैं अजगर में फिर से अधिक से अधिक निम्नलिखित छोटे कष्टप्रद दुविधा का सामना:पायथन: कई बार एक छोटी सूची बनाने के लिए कितना महंगा है?

विकल्प 1: (?)

क्लीनर लेकिन धीमी अगर कई बार कहा जाता है के बाद से a_list do_something की प्रत्येक कॉल के लिए फिर से बनाया हो()

def do_something():  
    a_list = ["any", "think", "whatever"]  
    # read something from a_list 

विकल्प 2:

भद्दा लेकिन अधिक कुशल

012 (a_list निर्माण फिर से अतिरिक्त)

आपको क्या लगता है?

+8

संदेह में, सबसे अधिक पठनीय, सुरुचिपूर्ण, स्वयं-दस्तावेज़ कोड के लिए जाएं जब तक कि एक प्रदर्शन प्रोफाइलर आपको नहीं बताता। –

+0

हाँ मुझे पता है। लेकिन यह ऐसी छोटी और परेशान और चीज़ से बचने में आसान है ... – GabiMe

+4

"छोटा" इसका अर्थ है इसे अनदेखा करें। जो भी सबसे स्पष्ट है वह करो। निष्पादन विचारों को एक तरफ छोड़ दें जब तक आप * साबित नहीं कर सकते * यह एक समस्या है। –

उत्तर

16

इसके बारे में बदसूरत क्या है?

क्या आपके उदाहरण में सूची की सामग्री हमेशा स्थिरांक है? यदि ऐसा है: पाइथन के हाल के संस्करण (2.4 के बाद से) निरंतर अभिव्यक्ति का मूल्यांकन करके और नतीजे को बनाए रखकर अनुकूलित करेंगे, लेकिन केवल तभी यह एक टुपल होगा। तो आप इसे एक टुपल के रूप में बदल सकते हैं।या आप इस तरह की छोटी चीजों के बारे में चिंता करना बंद कर सकते हैं।

>>> def afunc(): 
... a = ['foo', 'bar', 'zot'] 
... b = ('oof', 'rab', 'toz') 
... return 
... 
>>> import dis; dis.dis(afunc) 
    2   0 LOAD_CONST    1 ('foo') 
       3 LOAD_CONST    2 ('bar') 
       6 LOAD_CONST    3 ('zot') 
       9 BUILD_LIST    3 
      12 STORE_FAST    0 (a) 

    3   15 LOAD_CONST    7 (('oof', 'rab', 'toz')) 
      18 STORE_FAST    1 (b) 

    4   21 LOAD_CONST    0 (None) 
      24 RETURN_VALUE 
>>> 
+1

वास्तव में? मुझे यह नहीं पता था। उन tuples केवल एक बार बनाया जाने के लिए अनुकूलित हो जाता है। दिलचस्प .. यह शायद ओपी – GabiMe

+0

@AnonymousDriveByDownVoter के 90% मामलों को हल करेगा: एक टिप्पणी छोड़ने की देखभाल? –

4

यदि आपको ऐसा करने की ज़रूरत नहीं है तो कभी भी एक से अधिक बार कुछ न बनाएं। यह एक साधारण अनुकूलन है जो आपके हिस्से पर किया जा सकता है और मुझे व्यक्तिगत तौर पर दूसरा उदाहरण बदसूरत नहीं लगता है।

कुछ लोग इस तरह की छोटी चीजों को अनुकूलित करने के बारे में चिंता न करने का तर्क दे सकते हैं लेकिन मुझे लगता है कि इसे ठीक करने के लिए कुछ आसान होना चाहिए। मैं आपके एप्लिकेशन को किसी भी चीज की कई प्रतियां बनाने से नफरत करता हूं, जिसे "कोड सौंदर्य" की मनमाने ढंग से समझने के लिए बस इसकी आवश्यकता नहीं होती है। :)

3

यदि आपका a_list परिवर्तित नहीं होता है, तो इसे फ़ंक्शन से बाहर ले जाएं।

0

यदि सूची कभी संशोधित नहीं होती है, तो आप सूचियों का उपयोग क्यों करते हैं?

अपनी वास्तविक आवश्यकताओं को जानने के बिना, मैं सूची से छुटकारा पाने के लिए कुछ "अगर विवरण से कुछ पढ़ता हूं" भाग लेने के लिए बस कुछ कथन का उपयोग करने की सलाह दूंगा।

4

विकल्प 3:

def do_something(a_list = ("any", "think", "whatever")): 
    read something from a_list 

विकल्प 3 विकल्प 1 की तुलना में:

दोनों मेरी राय में समान रूप से पठनीय हैं (कुछ टिप्पणियों में अलग तरह से सोचने के लिए :-) लगते हैं, हालांकि!)। आप इस

def do_something(
    a_list = ("any", "think", "whatever")): 
    read something from a_list 

जैसे विकल्प 3 को भी लिख सकते हैं जो वास्तव में पठनीयता के संदर्भ में अंतर को कम करता है। विकल्प 1 के विपरीत, हालांकि, विकल्प 3 केवल a_list को परिभाषित करता है - उस समय जब do_something परिभाषित किया गया है। यही वही है जो हम चाहते हैं।

विकल्प 3 विकल्प 2 की तुलना में:

वैश्विक चर से बचें यदि संभव हो तो। विकल्प 3 आपको ऐसा करने की अनुमति देता है। इसके अलावा, विकल्प 2 के साथ, समय के साथ या यदि अन्य लोग इस कोड को बनाए रखते हैं, तो a_list की परिभाषा def do_something से अलग हो सकती है। यह एक बड़ा सौदा नहीं हो सकता है, लेकिन मुझे लगता है कि यह कुछ हद तक अवांछित है।

+3

Gneee ... क्षमा करें, एक डिफ़ॉल्ट पैरामीटर के रूप में एक सूची को देखता है दर्द होता है। –

+1

-1 "जब आप ध्वनि सलाह दे सकते हैं तो वैश्विक चर से बचें", लेकिन "पाइथन बल [डी] स्थानीय लोगों में चर के लिए पहली बार खोजने के लिए मजबूर है() dict" कोड codswallop है। COMPILER जानता है कि यह स्थानीय या वैश्विक है, और विकल्प 2 मामले में एक लोड वैश्विक निर्देश उत्सर्जित करता है। स्थानीय() निर्देश तब प्रकट होता है जब आप स्थानीय लोगों() फ़ंक्शन को कॉल करते हैं - COMPILER जानता है कि सभी स्थानीय कहां संग्रहीत किए जाते हैं; सामान्य फ़ंक्शन/विधि कोड चलाने के लिए कोई भी निर्देश नहीं उपयोग किया जाता है। –

1

खैर यह फंक्शन है या नहीं में सरणी आरंभ करने के लिए नीचे आता है लगता है::

import time 
def fun1(): 
     a = ['any', 'think', 'whatever'] 
     sum = 0 
     for i in range(100): 
       sum += i 

def fun2(): 
     sum = 0 
     for i in range(100): 
       sum += i 


def test_fun(fun, times): 
     start = time.time() 
     for i in range(times): 
       fun() 
     end=time.time() 
     print "Function took %s" % (end-start) 

# Test 
print 'warming up' 
test_fun(fun1, 100) 
test_fun(fun2, 100) 

print 'Testing fun1' 
test_fun(fun1, 100000) 
print 'Testing fun2' 
test_fun(fun2, 100000) 

print 'Again' 
print 'Testing fun1' 
test_fun(fun1, 100000) 
print 'Testing fun2' 
test_fun(fun2, 100000) 

और परिणाम:

यहाँ और स्थिरांक की एक सूची स्थिरांक की एक टपल है

>python test.py 
warming up 
Function took 0.000604152679443 
Function took 0.000600814819336 
Testing fun1 
Function took 0.597407817841 
Testing fun2 
Function took 0.580779075623 
Again 
Testing fun1 
Function took 0.595198154449 
Testing fun2 
Function took 0.580571889877 

ऐसा लगता है कि कोई अंतर नहीं है।

+1

'टाइमिट' मॉड्यूल का उपयोग अधिक उपयुक्त होगा ... – ChristopheD

+1

यदि आप do_fun1() कहीं कहलाते हैं तो यह मदद कर सकता है। ;-) –

+0

किसी फ़ंक्शन के अंदर इसे Nesting कुछ और पूरी तरह से है।उन शर्तों के तहत आज़माएं जिन पर हम चर्चा कर रहे हैं: (1) स्थानीय (2) वैश्विक (3) डिफ़ॉल्ट तर्क (4) स्थानीय लेकिन एक सूची के बजाय एक tuple के रूप में। लूप के लिए समय का भी हिस्सा खर्च किया जाता है जो सभी अप्रासंगिक है। लूप को फेंक दें, और एक विकल्प (0) में कोई सूची/टुपल फेंक दें (1) - (0), (2) - (0) आदि –

0

मैंने स्वचालित सिस्टम पर काम किया है जो एक दिन में 100,000,000+ रिकॉर्ड संसाधित करता है, जहां 1% प्रतिशत प्रदर्शन सुधार बड़ा होता है।

मैंने उस प्रणाली पर काम करने वाला एक बड़ा सबक सीखा: तेज़ बेहतर है, लेकिन केवल तभी जब आप जानते हैं कि यह पर्याप्त तेज़ है।

कुल प्रसंस्करण समय में 1% सुधार में भारी कमी आई होगी, लेकिन जब हमें हमारे अगले हार्डवेयर अपग्रेड की आवश्यकता होगी तो यह प्रभावी नहीं होगा। मेरा आवेदन इतना तेज़ था कि मैंने पिछले 1% दूध की कोशिश करने में कितना समय बिताया था, शायद नए सर्वर की तुलना में अधिक लागत होगी।

आपके मामले में, आपको प्रदर्शन में महत्वपूर्ण अंतर करने से पहले हजारों बार कुछ करना होगा। कुछ मामलों में इससे कोई फर्क पड़ता है, दूसरे में यह नहीं होगा।

2
  1. आप कुछ डेटा
  2. आप एक विधि यह
  3. तुम बस विधि की गति का अनुकूलन जब तक आप के लिए है के लिए विश्व स्तर पर डेटा रखने के लिए नहीं करना चाहते हैं के साथ जुड़े किया है।

मुझे लगता है कि यह कक्षाएं क्या हैं।

class Processor: 
    def __init__(this): 
     this.data = "any thing whatever".split() 
    def fun(this,arg): 
     # do stuff with arg and list 

inst = Processor() 
inst.fun("skippy) 

इसके अलावा, अगर तुम किसी दिन एक फ़ाइल में डेटा को अलग करना चाहते हैं, तो आप सिर्फ निर्माता ऐसा करने के लिए संशोधित कर सकते हैं।

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