2010-02-24 12 views
5

में अनावश्यक टुकड़ा नकल से बचना वहाँ इस तरह के मामलों के लिए व्यर्थ टुकड़ा नकल से बचने के लिए एक आम मुहावरा है। extend को देने के लिए स्मृति में एक नया टुकड़ा बनाने के बजाय मैं कहना चाहता हूं कि "वर्तमान वस्तु की केवल इस सीमा का उपयोग करें"।अजगर

कुछ तरीकों टुकड़ा मानकों के साथ तुम बाहर में मदद मिलेगी, उदाहरण के count के लिए:

>>> a = bytearray(1000000)  # a million zero bytes 
>>> a[0:900000].count(b'\x00') # expensive temporary slice 
900000 
>>> a.count(b'\x00', 0, 900000) # helpful start and end parameters 
900000 

लेकिन कई, मेरे पहले उदाहरण में extend की तरह, यह सुविधा नहीं है।

मुझे एहसास है कि मैं जिन अनुप्रयोगों के बारे में बात कर रहा हूं, उनके लिए माइक्रो-ऑप्टिमाइज़ेशन होगा, इसलिए किसी से पूछने से पहले - हाँ, मैंने अपना आवेदन प्रोफाइल किया है, और यह मेरे मामले के बारे में चिंता करने योग्य है।

मेरे पास नीचे एक 'समाधान' है, लेकिन किसी भी बेहतर विचार का स्वागत है।

उत्तर

5

एक buffer वस्तु टुकड़ा को कॉपी टाल बनाना, लेकिन कम स्लाइस के लिए यह सिर्फ प्रतिलिपि बनाने के लिए और अधिक कुशल है:

>>> a.extend(buffer(b, 14, 6)) 
>>> a 
bytearray(b'hello world') 

यहाँ प्रति केवल एक ही स्मृति से बना है, लेकिन buffer बनाने का खर्च बचत को खत्म करने से अधिक वस्तुएं। हालांकि यह बड़े स्लाइस के लिए बेहतर होना चाहिए। मुझे यकीन नहीं है कि इस विधि के लिए कुल मिलाकर अधिक कुशल होने के लिए टुकड़ा कितना बड़ा होगा।

ध्यान दें कि अजगर 3 के लिए (और अजगर 2.7 में वैकल्पिक रूप से) आप एक memoryview वस्तु के बजाय आवश्यकता होगी:

>>> a.extend(memoryview(b)[14:20]) 
+0

बफर बफर इंटरफेस का समर्थन करने वाली वस्तुओं के लिए एक अच्छा विकल्प है। आम तौर पर यह छोटे मामलों के लिए विशेष आवरण के लायक नहीं है (जब तक कि आपके अधिकांश उपयोग के मामले छोटे नहीं होते हैं) क्योंकि एक छोटी राशि से 50% अधिक अभी भी एक छोटी राशि –

2

itertoolsislice है। इस्लिस में कोई गिनती विधि नहीं है, इसलिए यह अन्य मामलों में उपयोगी है जहां आप स्लाइस की प्रतिलिपि से बचना चाहते हैं। जैसा कि आपने बताया - गिनती के लिए इसके लिए एक तंत्र है

>>> from itertools import islice 
>>> a = bytearray(1000000) 
>>> sum(1 for x in islice(a,0,900000) if x==0) 
900000 
>>> len(filter(b'\x00'.__eq__,islice(a,0,900000))) 
900000 

>>> a=bytearray(b"hello") 
>>> b = bytearray(b'goodbye, cruel world.') 
>>> a.extend(islice(b,14,20)) 
>>> a 
bytearray(b'hello world') 
+0

'islice' एक अच्छा विकल्प है। मैंने अभी कुछ त्वरित परीक्षण किए हैं और यह 'विस्तार' के साथ उपयोग किए जाने पर 'बफर' जितना तेज़ लगता है, हालांकि वे केवल एक टुकड़ा का उपयोग करने से भी अधिक * धीमे होते हैं, यहां तक ​​कि आधे मिलियन तत्वों के लिए भी ... –