2010-07-17 9 views
9

मैं हाल ही में पाइथन सीख रहा हूं, और भाषा के साथ कई अभ्यास कर रहा हूं।पायथन में, सूची से पढ़ने की तुलना में सरणी से धीमा क्यों पढ़ रहा है?

एक चीज़ जो मैंने दिलचस्प पाया वह यह है कि, जब मैं एक सरणी से पढ़ता हूं, तो यह सूची के मुकाबले धीमा समय का आधा होता है। क्या किसी को पता है क्यों?

 
from timeit import Timer 
import array 

t = 10000 
l = range(t) 
a = array.array('i', l) 
def LIST(): 
    for i in xrange(t): 
     l[i] 

def ARRAY(): 
    for i in xrange(t): 
     a[i] 

print Timer(LIST).timeit(1000); 
print Timer(ARRAY).timeit(1000); 

उत्पादन होता है:

यहाँ मेरी कोड है

 
0.813191890717 
1.16269612312 

जो इंगित करता है कि पढ़ने वालों सूची की तुलना में धीमी है। मुझे लगता है कि सरणी एक निश्चित आकार मेमोरी है, जबकि सूची एक गतिशील संरचना है। तो मुझे लगता है कि सरणी सूची से तेज होगी।

क्या किसी के पास कोई स्पष्टीकरण है?

+1

संभव डुप्ली/उत्तर: http://stackoverflow.com/questions/176011/python-list-vs-array-when-to-use - मूल रूप से array.array एक सी सरणी के चारों ओर एक रैपर है, इसलिए मुझे लगता है कि वहां है इसे एक्सेस करते समय ओवरहेड। गणित के लिए इसका इस्तेमाल न करें। –

+0

दूसरी अनुमान लगाने की कोशिश कर पाइथन क्षमता - खासकर सी-जैसी पृष्ठभूमि से आने वाले लोगों के लिए - अक्सर काउंटर-सहज ज्ञान युक्त होता है। कोड स्पष्ट रूप से पहले, फिर यदि आप प्रदर्शन समस्या को मापते हैं तो अनुकूलित करें; यह सी पर भी लागू होता है, लेकिन क्योंकि भाषा तत्व मशीन के बहुत करीब हैं, लोग अक्सर भूल जाते हैं। – msw

+1

गणित के लिए आप numpy (अभी तक पायथन 3 के लिए उपलब्ध नहीं) का उपयोग करना चाह सकते हैं, केवल भगवान जानता है कि क्यों numpy मानक पुस्तकालय नहीं है। –

उत्तर

8

पाइथन int में कच्चे पूर्णांक को लपेटने में समय लगता है।

+2

काफी। फ़ंक्शन सूची केवल बढ़ाना है और फिर प्रत्येक सूची तत्व के लिए संदर्भ गणना को कम करना है। दूसरी तरफ ARRAY फ़ंक्शन को प्रत्येक पूर्णांक के लिए स्मृति आवंटित करना है (छोटे को छोड़कर जिनके पास अनुकूलन है) और फिर इसे फिर से मुक्त करें। – Duncan

1

पायथन सूची वास्तव में कुछ तरीकों से सामान्य सरणी जैसा दिखती है, वे लिस्प सूची नहीं हैं, लेकिन उनके पास तेजी से यादृच्छिक पहुंच है।

8

list s "गतिशील रूप से बढ़ रही वैक्टर" (बहुत ज्यादा की तरह सी ++ के std::vector, कहते हैं) कर रहे हैं लेकिन यह है कि कोई रास्ता नहीं में नीचे उन्हें रैंडम एक्सेस (वे सूचियों जुड़ा हुआ नहीं रहे हैं! -) धीमा कर देती है। सूचियों की प्रविष्टियां पाइथन ऑब्जेक्ट्स (आइटम) के संदर्भ हैं: किसी को एक्सेस करने के लिए केवल (सीपीथॉन में) आइटम की संदर्भ गणना की वृद्धि (अन्य कार्यान्वयन में, अधिक उन्नत कचरा संग्रह के आधार पर, यहां तक ​​कि ;-) भी नहीं है। ऐरे की प्रविष्टियां कच्चे बिट्स और बाइट्स हैं: किसी को एक्सेस करने के लिए उस बाइनरी मान के आधार पर एक नया नया पायथन ऑब्जेक्ट संश्लेषित किया जाना आवश्यक है। तो उदाहरण:

$ python -mtimeit -s'import array; c=array.array("B", "bzap")' 'c[2]' 
10000000 loops, best of 3: 0.0903 usec per loop 
$ python -mtimeit -s'c=list("bzap")' 'c[2]' 
10000000 loops, best of 3: 0.0601 usec per loop 

30 नैनोसेकंद का उपयोग अतिरिक्त समय के लिए बहुत बुरा नहीं लगता ;-)।

एक तरफ के रूप में, ध्यान दें कि timeit कमांड लाइन से उपयोग करने के लिए बहुत अच्छा है - पुनरावृत्ति की स्वत: पसंद, समय के लिए दिखाए गए माप की इकाई इत्यादि। इस तरह मैं हमेशा इसका उपयोग करता हूं (एक कस्टम-कोडित मॉड्यूल आयात करना यदि आवश्यक हो तो कार्यों को बुलाया जा सकता है - लेकिन यहां इसकी कोई आवश्यकता नहीं है) - यह है इसलिए मॉड्यूल से आयात करने और इसका उपयोग करने से कहीं अधिक आसान है!

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