2016-11-17 12 views
14

तो यह एक CPython बात है, यह एक ही व्यवहार है काफी यकीन नहीं है कि अन्य कार्यान्वयन के साथ।'{0}'। प्रारूप() str से() और '{}' तेज है। प्रारूप() IPython% timeit का उपयोग कर और नहीं तो शुद्ध अजगर का उपयोग कर

लेकिन '{0}'.format()str() और '{}'.format() से तेज़ है। मैं अजगर 3.5.2 से परिणाम पोस्टिंग कर रहा हूँ, लेकिन, मैं साथ इसे करने की कोशिश अजगर 2.7.12 और प्रवृत्ति में ही है।

%timeit q=['{0}'.format(i) for i in range(100, 100000, 100)] 
%timeit q=[str(i) for i in range(100, 100000, 100)] 
%timeit q=['{}'.format(i) for i in range(100, 100000, 100)] 

1000 loops, best of 3: 231 µs per loop 
1000 loops, best of 3: 298 µs per loop 
1000 loops, best of 3: 434 µs per loop 

docs से object.__str__(self)

str(object) द्वारा कहा जाता है और बिल्ट-इन कार्य format() और print() पर एक वस्तु का "अनौपचारिक" या अच्छी तरह से प्रिंट करने योग्य स्ट्रिंग प्रतिनिधित्व गणना करने के लिए।

तो, str() और format() कॉल एक ही object.__str__(self) विधि, लेकिन जहां गति में है कि अंतर से आता है?

अद्यतन @StefanPochmann और @Leon टिप्पणियों में नोट किया गया, उन्हें अलग-अलग परिणाम मिलते हैं। मैं python -m timeit "..." साथ इसे चलाने के लिए कोशिश की और, वे सही हैं, क्योंकि परिणाम हैं:

$ python3 -m timeit "['{0}'.format(i) for i in range(100, 100000, 100)]" 
1000 loops, best of 3: 441 usec per loop 

$ python3 -m timeit "[str(i) for i in range(100, 100000, 100)]" 
1000 loops, best of 3: 297 usec per loop 

$ python3 -m timeit "['{}'.format(i) for i in range(100, 100000, 100)]" 
1000 loops, best of 3: 420 usec per loop 

तो ऐसा लगता है कि IPython कुछ अजीब कर रहा है ...

नया सवाल: क्या पसंद किया जाता है जिस तरह से किसी ऑब्जेक्ट को str पर गति से परिवर्तित करने के लिए?

+0

तेज होने के लिए, आप सीधे 'i .__ str __()' का उपयोग करने का प्रयास कर सकते हैं। हालांकि 'str' वास्तव में सही तरीका है। क्या यह आपके लिए पर्याप्त तेज़ नहीं है? –

उत्तर

7

आईपीथन समय कुछ कारणों से बंद है (हालांकि, जब विभिन्न कोशिकाओं में एक लंबे प्रारूप स्ट्रिंग के साथ परीक्षण किया जाता है, तो यह थोड़ा बेहतर व्यवहार करता है)। शायद एक ही कोशिकाओं में निष्पादन सही नहीं है, वास्तव में नहीं जानते हैं।

किसी भी तरह से, "{}" थोड़ा "{pos}" जो "{name}" तेजी से है, जबकि वे str से सभी धीमी कर रहे हैं की तुलना में तेजी है।

str(val)str को कोई चीज को बदलने के लिए सबसे तेज़ तरीका है; यह ऑब्जेक्ट्स __str__ को सीधे कॉल करता है, यदि कोई मौजूद है, और परिणामी स्ट्रिंग देता है। अन्य, जैसे format, (या str.format) अतिरिक्त फ़ंक्शन कॉल (format स्वयं) के कारण अतिरिक्त ओवरहेड शामिल हैं; किसी भी तर्क से निपटने, प्रारूप स्ट्रिंग और को पार्स तो उनके args की __str__ लागू।

str.format तरीकों "{}" के लिए स्वत: नंबर का उपयोग करता है;

संस्करण 3.1 में परिवर्तित:: docs on the format syntax में एक छोटा सा भाग से स्थितीय तर्क विनिर्देशक छोड़ा जा सकता है, तो '{} {}''{0} {1}' के बराबर है।

कि है, यदि आप प्रपत्र की एक स्ट्रिंग की आपूर्ति:

"{}{}{}".format(1, 2, 3) 

CPython तुरंत जानता है कि इस के बराबर है:

"{0}{1}{2}".format(1, 2, 3) 

एक प्रारूप स्ट्रिंग कि संख्या शामिल साथ पदों का संकेत; CPython एक सख्ती से बढ़ती हुई संख्या (कि 0 से शुरू होता है) कल्पना नहीं कर सकते और व्यवस्था यह सही, इस प्रक्रिया में थोड़ा नीचे बातें धीमा में प्राप्त करने के लिए हर एक ब्रैकेट पार्स करना होगा:

"{1}{2}{0}".format(1, 2, 3) 

इसलिए यह भी नहीं है इन दोनों को एक साथ मिश्रण करने की अनुमति दी:

"{1}{}{2}".format(1, 2, 3) 

आप एक अच्छे ValueError वापस मिल जाएगा जब आप ऐसा करने का प्रयास: यह

ValueError: cannot switch from automatic field numbering to manual field specification 

इन positionals with PySequence_GetItem को भी पकड़ लेता है, जो मुझे लगता है कि कम से कम PyObject_GetItem की तुलना में तेज़ है [अगला देखें]।

"{name}" मानों के लिए, सीपीथन हमेशा इस तथ्य के कारण अतिरिक्त काम करता है कि हम स्थितित्मक लोगों की बजाय कीवर्ड तर्कों से निपट रहे हैं; इसमें key एस और मानों को लोड करने के लिए कॉल के लिए शब्दकोश बनाने और LOAD बाइट-कोड निर्देशों को उत्पन्न करने जैसी चीजें शामिल हैं। फंक्शन कॉलिंग का कीवर्ड फॉर्म हमेशा कुछ ओवरहेड पेश करता है। इसके अलावा, ऐसा लगता है कि हथियाने वास्तव में PyObject_GetItem का उपयोग करता है जो इसकी सामान्य प्रकृति के कारण कुछ अतिरिक्त ओवरहेड का उपयोग करता है।

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