अजगर में str प्रदर्शन


88

अजगर कोड ( python 2.6ऊपर 3.2) का एक टुकड़ा प्रोफाइलिंग करते हुए , मैंने पाया कि strकिसी वस्तु (मेरे मामले में पूर्णांक) को स्ट्रिंग में बदलने की विधि स्ट्रिंग प्रारूपण का उपयोग करने की तुलना में परिमाण धीमी का एक क्रम है।

यहाँ बेंचमार्क है

>>> from timeit import Timer
>>> Timer('str(100000)').timeit()
0.3145311339386332
>>> Timer('"%s"%100000').timeit()
0.03803517023435887

क्या किसी को पता है कि यह मामला क्यों है? क्या मैं कुछ भूल रहा हूँ?


2
और के बारे में क्या'{}'.format(100000)
विम

यह सबसे धीमी है, लेकिन सबसे अधिक लचीली भी है।
लुका सर्बडेला

जवाबों:


106

'%s' % 100000 संकलक द्वारा मूल्यांकन किया जाता है और रन-टाइम में एक स्थिर के बराबर होता है।

>>> import dis
>>> dis.dis(lambda: str(100000))
  8           0 LOAD_GLOBAL              0 (str)
              3 LOAD_CONST               1 (100000)
              6 CALL_FUNCTION            1
              9 RETURN_VALUE        
>>> dis.dis(lambda: '%s' % 100000)
  9           0 LOAD_CONST               3 ('100000')
              3 RETURN_VALUE        

%रन-टाइम अभिव्यक्ति के साथ (महत्वपूर्ण रूप से) तेज नहीं है str:

>>> Timer('str(x)', 'x=100').timeit()
0.25641703605651855
>>> Timer('"%s" % x', 'x=100').timeit()
0.2169809341430664

ध्यान दें कि strअभी भी थोड़ा धीमा है, जैसा कि @DietrichEpp ने कहा, इसका कारण यह है कि strइसमें लुकअप और फंक्शन कॉल ऑपरेशंस शामिल हैं, जबकि %एक ही तत्काल बायोटेक के लिए संकलित किया गया है:

>>> dis.dis(lambda x: str(x))
  9           0 LOAD_GLOBAL              0 (str)
              3 LOAD_FAST                0 (x)
              6 CALL_FUNCTION            1
              9 RETURN_VALUE        
>>> dis.dis(lambda x: '%s' % x)
 10           0 LOAD_CONST               1 ('%s')
              3 LOAD_FAST                0 (x)
              6 BINARY_MODULO       
              7 RETURN_VALUE        

बेशक उपरोक्त प्रणाली के लिए सही है जिस पर मैंने परीक्षण किया था (सीपीथॉन 2.7); अन्य कार्यान्वयन भिन्न हो सकते हैं।


वास्तव में यह कारण जैसा दिखता है, मैंने सिर्फ अपने आप को आजमाया और स्ट्रिंग प्रारूपण की तुलना में लगभग 5% तेज है str। उत्तर के लिए धन्यवाद। हर जगह कोड बदलने का कोई कारण नहीं :-)
लुका सर्बडेला

2
आगे विस्तृत करने के लिए: str एक ऐसा नाम है जिसे स्ट्रिंग प्रकार के अलावा किसी अन्य चीज़ के लिए रिबाउंड किया जा सकता है, लेकिन स्ट्रिंग प्रारूपण - अर्थात str.__mod__विधि - को प्रतिस्थापित नहीं किया जा सकता है, जो संकलक को अनुकूलन करने की अनुमति देता है। कंपाइलर अनुकूलन के रास्ते में बहुत कुछ नहीं करता है, लेकिन यह आपको लगता है कि अधिक से अधिक करता है :)
कार्ल Knechtel

4
... और यहाँ सीखने के लिए सबक है: इन जैसे परीक्षणों में कभी भी शाब्दिक का उपयोग न करें!
अंकलजीव

इस विशेष ब्लॉग प्रविष्टि में आपकी रुचि हो सकती है: skymind.com/~ocrow/python_string । इसमें आपके द्वारा प्रदान किए गए के समान विभिन्न स्ट्रिंग संयोजन विधियों के लिए बेंचमार्क का एक चार्ट है।
आरोन न्यूटन

14

एक कारण जो दिमाग में आता है, वह तथ्य यह है कि str(100000)इसमें एक वैश्विक खोज शामिल है, लेकिन "%s"%100000ऐसा नहीं है। strवैश्विक वैश्विक क्षेत्र में देखा जाना चाहिए। यह पूरे अंतर के लिए जिम्मेदार नहीं है:

>>> Timer('str(100000)').timeit()
0.2941889762878418
>>> Timer('x(100000)', 'x=str').timeit()
0.24904918670654297

द्वारा नोट किया गया thg435 ,

>>> Timer('"%s"%100000',).timeit()
0.034214019775390625
>>> Timer('"%s"%x','x=100000').timeit()
0.2940788269042969
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.