हैरानी की बात है, मुझे लगता है startswith
in
की तुलना में धीमी है:स्ट्रिंग की शुरुआत धीमी गति से क्यों होती है?
In [10]: s="ABCD"*10
In [11]: %timeit s.startswith("XYZ")
1000000 loops, best of 3: 307 ns per loop
In [12]: %timeit "XYZ" in s
10000000 loops, best of 3: 81.7 ns per loop
हम सभी जानते हैं, in
आपरेशन पूरी स्ट्रिंग खोज करने के लिए की जरूरत है और startswith
सिर्फ पहले कुछ वर्ण की जाँच करने की जरूरत है, तो startswith
अधिक कुशल होना चाहिए ।
जब s
काफी बड़ा है, startswith
तेजी से होता है:
In [13]: s="ABCD"*200
In [14]: %timeit s.startswith("XYZ")
1000000 loops, best of 3: 306 ns per loop
In [15]: %timeit "XYZ" in s
1000000 loops, best of 3: 666 ns per loop
तो ऐसा लगता है कि फोन करने startswith
कुछ भूमि के ऊपर है जो इसे धीमा हो जाता है जब स्ट्रिंग छोटा है है।
और मैंने यह पता लगाने की कोशिश की कि startswith
कॉल का ओवरहेड क्या है।
In [16]: f=s.startswith
In [17]: %timeit f("XYZ")
1000000 loops, best of 3: 270 ns per loop
इसके अलावा, मैं एक की लागत का परीक्षण किया: - के रूप में इस answer में उल्लेख किया है - यहाँ हम startswith
देख सकते हैं अभी भी धीमी
पहले, मैं एक f
चर इस्तेमाल किया डॉट आपरेशन की लागत को कम करने के लिए खाली समारोह कॉल:
In [18]: def func(a): pass
In [19]: %timeit func("XYZ")
10000000 loops, best of 3: 106 ns per loop
डॉट संचालन और समारोह कॉल की लागत के बावजूद, startswith
के समय के बारे में (270-106) = 164ns है, लेकिन in
आपरेशन तक केवल 81.7ns एसएस। ऐसा लगता है कि अभी भी startswith
के लिए कुछ ओवरहेड हैं, वह क्या है?
startswith
और __contains__
के बीच परीक्षा परिणाम के रूप में प्रहार और LVC ने सुझाव दिया जोड़ें:
In [28]: %timeit s.startswith("XYZ")
1000000 loops, best of 3: 314 ns per loop
In [29]: %timeit s.__contains__("XYZ")
1000000 loops, best of 3: 192 ns per loop
अधिक समान परिणाम प्राप्त करने के लिए, आप कर सकते हैं .__ में __ ("XYZ") है क्योंकि यह 's.startswith (" XYZ ") के समान मार्ग लेगा (फिर 'in' ऑपरेटर का उपयोग करेगा सदस्य का उपयोग कम करें)। हालांकि, तब भी 'startwith' मेरे लिए धीमा है। – poke
मुझे लगता है कि प्रदर्शन अंतर का शेष '__contains__' पूरी तरह से टाइप किया गया है * सी * में, जबकि 'startwith' वास्तविक तर्क पार्सिंग और सामान करता है (आप एक ट्यूपल भी पास कर सकते हैं)। – poke
पाइथन का कौन सा संस्करण आप उपयोग कर रहे हैं? 3.4.3 पर, मुझे 's.startswith (" XYZ ") 'रिपोर्ट 153ns मिलती है, और' s .__ में __ ("XYZ")' रिपोर्ट 16 9ns होती है। जैसा कि @ पोक कहते हैं, 'इन' का उपयोग करके विधि कॉल की तुलना में पूरी तरह से अलग लुकअप नियमों का उपयोग किया जाएगा - इसे सी स्तर पर फ़ंक्शन पॉइंटर से सीधे देखा जा सकता है, जबकि विधि लुकअप दो शब्दकोश खोज करता है और * फिर * करना है एक पायथन-स्तर समारोह कॉल। उन चीजों को अलग-अलग समय पर आपको अंतर के कुछ * विचार दे सकते हैं, लेकिन यह आवश्यक नहीं है। आपकी संख्याओं पर, उन ओवरहेड दोनों को घटाना 'startwith' * नकारात्मक * के लिए समय बनाता है! – lvc