मैं एक कस्टम इटरेटर के साथ एक छोटे कंटेनर पर फिर से शुरू होने पर आश्चर्यजनक प्रदर्शन अंतर की तरह लग रहा हूं। मैं उम्मीद कर रहा था कि कोई मुझे यह समझने में सक्षम हो सकता है कि ये मतभेद कहां से आ रहे हैं।कस्टम इटरेटर प्रदर्शन
पहले कुछ संदर्भ; मैं बूस्ट :: पायथन का उपयोग करके कई पायथन एक्सटेंशन मॉड्यूल लिख रहा हूं, जिनमें से एक 3 डी फ्लोट वेक्टर प्रकार के लिए बाध्यकारी है जो getitem लागू करता है। चूंकि इसे इसके ऊपर फिर से शुरू करना संभव है, हालांकि यह काफी धीमा लगता है, लेकिन यह स्पष्ट नहीं है कि मैंने चीजों को कैसे काम करते हैं, इस बारे में बेहतर विचार पाने के लिए मैंने पाइथन में कुछ सरल कस्टम इटरेटर्स के साथ खेलने का फैसला किया। कौन सा है, जहां इन iterators से आया है ...
class MyIterator1(object):
__slots__ = ['values', 'popfn']
def __init__(self):
self.values = ['x', 'y', 'z']
self.popfn = self.values.pop
def __length_hint__(self):
return 3
def __iter__(self):
return self
def next(self):
try:
return self.popfn()
except IndexError:
raise StopIteration
class MyIterator2(object):
__slots__ = ['values', 'itfn']
def __init__(self):
self.values = ['x', 'y', 'z']
it = iter(self.values)
self.itfn = it.next
def __length_hint__(self):
return 3
def __iter__(self):
return self
def next(self):
return self.itfn()
class MyIterator3(object):
__slots__ = ['values', 'i']
def __init__(self):
self.values = ['x', 'y', 'z']
self.i = 0
def __length_hint__(self):
return 3
def __iter__(self):
return self
def next(self):
if self.i >= 3:
raise StopIteration
value = self.values[self.i]
self.i += 1
return value
def MyIterator4():
val = ['x', 'y', 'z']
yield val[0]
yield val[1]
yield val[2]
अगला मैं timeit मॉड्यूल के साथ एक स्क्रिप्ट (जो मान लिया गया है इसके बाद के संस्करण कोड एक मॉड्यूल कहा जाता testiter में है)
import timeit
timer1 = timeit.Timer('r = list(testiter.MyIterator1())', 'import testiter')
timer2 = timeit.Timer('r = list(testiter.MyIterator2())', 'import testiter')
timer3 = timeit.Timer('r = list(testiter.MyIterator3())', 'import testiter')
timer4 = timeit.Timer('r = list(testiter.MyIterator4())', 'import testiter')
timer5 = timeit.Timer('r = list(iter(["x", "y", "z"]))', 'import testiter')
print 'list(testiter.MyIterator1())'
print timer1.timeit()
print "\n"
print 'list(testiter.MyIterator2())'
print timer2.timeit()
print "\n"
print 'list(testiter.MyIterator3())'
print timer3.timeit()
print "\n"
print 'list(testiter.MyIterator4())'
print timer4.timeit()
print "\n"
print 'list(iter(["x", "y", "z"]))'
print timer5.timeit()
यह प्रिंट के माध्यम से इन भागा निम्नलिखित
list(testiter.MyIterator1())
8.5735929
list(testiter.MyIterator2())
5.28959393501
list(testiter.MyIterator3())
6.11230111122
list(testiter.MyIterator4())
2.31263613701
list(iter(["x", "y", "z"]))
1.26243281364
अनजाने में पाइथन लिस्टिटरेटर काफी मार्जिन से सबसे तेज़ है। मुझे लगता है कि यह पाइथन के भीतर कुछ जादू अनुकूलन के लिए नीचे है। जनरेटर माईइटरेटर कक्षाओं की तुलना में काफी तेज़ है, जो कि मैं फिर से आश्चर्यचकित नहीं हूं, और मान लीजिए कि सी में किए गए सभी कामों के कारण, हालांकि यह अनुमान है। अब दूसरों को और अधिक भ्रमित/आश्चर्यजनक हैं। क्या वे इस संदर्भ में प्रतीत होते हैं या कथन को छोड़कर कोशिश कर रहे हैं या कुछ और चल रहा है?
इन मतभेदों को समझाने में कोई मदद की सराहना की जाएगी! लंबी पोस्ट के लिए माफ़ी।
आप [x ',' y ',' z '] (जहां संभव हो) के बजाय tuple का उपयोग करने का प्रयास कर सकते हैं: tuple निर्माण सूची की तुलना में थोड़ा तेज़ है। –