2012-01-05 17 views
5

चेतावनी, यह एक सा पुनरावर्ती है;)समय कार्यों

मैं इस सवाल का जवाब: Python:How can i get all the elements in a list before the longest element?

और बाद मैं वहाँ प्रस्तुत जहां एक और जवाब यह है कि तेजी से होना चाहिए (लेखक सोचा, और इसलिए मैंने किया था) । मैंने अलग-अलग समाधानों का समय देने की कोशिश की लेकिन समाधान जो धीमा होना चाहिए वास्तव में तेज़ था। इससे मुझे लगता है कि मेरे कोड में कुछ गड़बड़ है। या यह है?

import string 
import random 
import time 

def solution1(lst): 
    return lst[:lst.index(max(lst, key=len))] 

def solution2(lst): 
    idx, maxLenStr = max(enumerate(lst), key=lambda x:len(x[1])) 
    return lst[:idx] 

# Create a 100000 elements long list that contains 
# random data and random element length 
lst = [] 
for i in range(100000): 
    s = "".join([random.choice(string.letters+string.digits) for x in range(1, random.randint(1,50))]) 
    lst.append(s) 

# Time the first solution 
start = time.time() 
solution1(lst) 
print 'Time for solution1', (time.time() - start) 

# Time the second solution 
start = time.time() 
solution2(lst) 
print 'Time for solution2', (time.time() - start) 

अद्यतन

किसी को भी उल्लेख है इससे पहले कि मैं क्यों डाल यह एक नया सवाल के रूप में है। प्रश्न मेरे बारे में अधिक जानकारी है कि निष्पादन समय को मापने के तरीके ...

+1

की छंटनी की है इन दोनों कार्यों में एक ही प्रकार नहीं लौटते वस्तु – joaquin

+0

रवींद्र की! बेशक :) धन्यवाद! –

+0

इसे फिक्स्ड। लेकिन यह भी मेरे कोड को तेज़ी से बनाता है ... और मैंने अभी भी सोचा कि समाधान 2 तेज हो जाएगा .. –

उत्तर

3

लैम्ब्डा दूसरा समाधान में मंहगा की लागत में तेजी से एक है का एक और उदाहरण है।

मैं दोनों कोड प्रोफाइल और प्रोफ़ाइल डेटा से, ऐसा लगता है, पहली समाधान है तेजी से

wiki कहेंगे समारोह कॉल महंगा है और दूसरा समाधान में, लैम्ब्डा और लेन फ़ंक्शन कॉल हैं यह धीमी

कृपया ध्यान दें चलाने बनाने, मैं नीचे सूची लंबाई 1000 तत्वों

>>> cProfile.run('solution1(lst)') 
     5 function calls in 0.000 CPU seconds 

    Ordered by: standard name 

    ncalls tottime percall cumtime percall filename:lineno(function) 
     1 0.000 0.000 0.000 0.000 <pyshell#305>:1(solution1) 
     1 0.000 0.000 0.000 0.000 <string>:1(<module>) 
     1 0.000 0.000 0.000 0.000 {max} 
     1 0.000 0.000 0.000 0.000 {method 'disable' of '_lsprof.Profiler' objects} 
     1 0.000 0.000 0.000 0.000 {method 'index' of 'list' objects} 


>>> cProfile.run('solution2(lst)') 
     2004 function calls in 0.012 CPU seconds 

    Ordered by: standard name 

    ncalls tottime percall cumtime percall filename:lineno(function) 
     1 0.000 0.000 0.012 0.012 <pyshell#306>:1(solution2) 
    1000 0.006 0.000 0.009 0.000 <pyshell#306>:2(<lambda>) 
     1 0.000 0.000 0.012 0.012 <string>:1(<module>) 
    1000 0.003 0.000 0.003 0.000 {len} 
     1 0.003 0.003 0.012 0.012 {max} 
     1 0.000 0.000 0.000 0.000 {method 'disable' of '_lsprof.Profiler' objects} 
+0

मैं सभी उत्तरों को स्वीकार करना चाहता हूं क्योंकि वे मूल्यवान हैं। लेकिन मैं केवल एक चुन सकता हूं और मुझे लगता है कि यह सबसे अच्छा स्पष्टीकरण था। धन्यवाद :) –

2

समय ठीक दिखता है।

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

+0

@joaquin हां, आप सही हैं। मैं किसी भी भ्रम से बचने के लिए अपनी टिप्पणी हटा रहा हूं। मुझे बताने के लिए धन्यवाद। – jcollado

3

ऐसा लगता है कि पहला संस्करण दूसरे की तुलना में बहुत कम कॉल कर रहा है।

btw, यह शायद कैसे मुहावरेदार, सरल कोड अक्सर भी अजगर

>>> dis.dis(solution1) 
    2   0 LOAD_FAST    0 (lst) 
       3 LOAD_FAST    0 (lst) 
       6 LOAD_ATTR    0 (index) 
       9 LOAD_GLOBAL    1 (max) 
      12 LOAD_FAST    0 (lst) 
      15 LOAD_CONST    1 ('key') 
      18 LOAD_GLOBAL    2 (len) 
      21 CALL_FUNCTION   257 
      24 CALL_FUNCTION   1 
      27 SLICE+2    
      28 RETURN_VALUE   
>>> dis.dis(solution2) 
    2   0 LOAD_GLOBAL    0 (max) 
       3 LOAD_GLOBAL    1 (enumerate) 
       6 LOAD_FAST    0 (lst) 
       9 CALL_FUNCTION   1 
      12 LOAD_CONST    1 ('key') 
      15 LOAD_CONST    2 (<code object <lambda> at 000000000422BEB8, file "<input>", line 2>) 
      18 MAKE_FUNCTION   0 
      21 CALL_FUNCTION   257 
      24 UNPACK_SEQUENCE   2 
      27 STORE_FAST    1 (idx) 
      30 STORE_FAST    2 (maxLenStr) 

    3   33 LOAD_FAST    0 (lst) 
      36 LOAD_FAST    1 (idx) 
      39 SLICE+2    
      40 RETURN_VALUE 
+0

इससे कोई फर्क नहीं पड़ता। किसी भी बड़े डेटा के लिए बुलाए गए कार्यों को और अधिक समय लगता है। – zch

+0

@zch क्षमा करें मुझे यह नहीं मिला, क्या आप अपनी टिप्पणी समझा सकते हैं? – joaquin

+0

सभी निर्देशों को प्रति परीक्षण केवल एक बार कहा जाता है। फ़ंक्शन 'अधिकतम' का चलने का समय इनपुट सूची की लंबाई के समान होता है। इसलिए, बड़ी पर्याप्त सूची के लिए (इस मामले में वास्तव में बड़ा नहीं), 'अधिकतम' चलाना अन्य निर्देशों को निष्पादित करने से कहीं अधिक समय लेगा। – zch

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