2010-07-11 4 views
5

निम्नलिखित कोड (here से, परीक्षण की संख्या में वृद्धि के साथ) पर विचार करें:इस कोड के लिए पायथन 3.1 2.6 से धीमा क्यों है?

from timeit import Timer 

def find_invpow(x,n): 
    """Finds the integer component of the n'th root of x, 
    an integer such that y ** n <= x < (y + 1) ** n. 
    """ 
    high = 1 
    while high ** n < x: 
     high *= 2 
    low = high/2 
    while low < high: 
     mid = (low + high) // 2 
     if low < mid and mid**n < x: 
      low = mid 
     elif high > mid and mid**n > x: 
      high = mid 
     else: 
      return mid 
    return mid + 1 

def find_invpowAlt(x,n): 
    """Finds the integer component of the n'th root of x, 
    an integer such that y ** n <= x < (y + 1) ** n. 
    """ 
    low = 10 ** (len(str(x))/n) 
    high = low * 10 
    while low < high: 
     mid = (low + high) // 2 
     if low < mid and mid**n < x: 
      low = mid 
     elif high > mid and mid**n > x: 
      high = mid 
     else: 
      return mid 
    return mid + 1 

x = 237734537465873465 
n = 5 
tests = 1000000 

print "Norm", Timer('find_invpow(x,n)', 'from __main__ import find_invpow, x,n').timeit(number=tests) 
print "Alt", Timer('find_invpowAlt(x,n)', 'from __main__ import find_invpowAlt, x,n').timeit(number=tests) 

अजगर 2.6 (Python 2.6.5 (r265:79063, Apr 16 2010, 13:57:41) [GCC 4.4.3] on linux2) का उपयोग करना, बार सूचित कर रहे हैं:

Norm 9.869 
Alt 9.53973197937 

हालांकि, एक ही मशीन पर अजगर 3.1 (Python 3.1.2 (r312:79147, Apr 15 2010, 15:35:48) [GCC 4.4.3] on linux2) का उपयोग कर, समय है:

Norm 28.4206559658 
Alt 26.8007400036 

क्या किसी को पता है कि क्यों इस कॉड ई पायथन 3.1 पर तीन गुना धीमी गति से चलता है?

+1

कोई रेप्रो: python3.1 2.6 की तुलना में तेजी के बारे में 30% की मेरी मशीन पर है। – SilentGhost

+0

धन्यवाद। आप कौन सा ओएस चला रहे हैं? मुझे उबंटू 10.04 64-बिट पर उपर्युक्त समय मिलता है। – user200783

+0

उसी सिस्टम के 32-बिट संस्करण – SilentGhost

उत्तर

3

मुझे 2.5, 2.6, 2.7 और 3.1 (विंडोज एक्सपी एसपी 2) ... "संस्करण के साथ तेजी से घटने का समय मिला। // के साथ, 3.1 गुणा 2.X गुना से नाटकीय रूप से छोटे थे। "सामान्य" 6.35 (py2.7) से 3.62 (py3.1) से गिरा दिया गया।

ध्यान दें कि 2.x में, इन्स (मशीन शब्द, 32 या 64 बिट्स) और लम्बे (चर लंबाई) हैं। 3.x में, लंबे समय से int का नाम बदल दिया गया है, और int दूर चला गया। मेरा अनुमान है कि लंबे समय से फ्लोट में कनवर्ट करने से अतिरिक्त समय/के साथ हो सकता है।

किसी भी मामले में, एक बेहतर "Alt" संस्करण इस कोड के साथ शुरू होगा:

high = 1 
highpown = 1 
while highpown < x: 
    high <<= 1 
    highpown <<= n 
+0

"इस कोड के साथ शुरू होगा" ... "। 'Low = high // 2' द्वारा पीछा किया गया? – user200783

+0

@ पॉल बेकर: बेशक। 'कम = उच्च/2' दोनों कार्यों में एक बग है। –

+1

+1। मुझे दृढ़ता से संदेह है कि यह 'int' बनाम 'लंबा' पहलू है जो एक फर्क पड़ता है। ध्यान दें कि 32-बिट मशीन पर, परीक्षण किए जाने वाले मान एक int में फिट नहीं होंगे, इसलिए आप पाइथन 2.x और 3.x दोनों में लंबे समय तक गणना कर रहे होंगे। लेकिन 64-बिट मशीन पर, आप 2.x में 'int' अंकगणित का उपयोग कर रहे हैं और 3.x में मनमाने ढंग से सटीक अंकगणितीय का उपयोग कर रहे हैं। –

2

// ऑपरेटर जबकि / ऑपरेटर अजगर 2 दिया पूर्णांक ऑपरेंड और अजगर 3 में सच विभाजन किसी भी ऑपरेंड दिया में फर्श विभाजन करता है, दोनों अजगर 2 और 3 में पूर्णांक विभाजन (या फर्श विभाजन) करता है।

// ऑपरेटर के साथ / ऑपरेटर को बदलने का प्रयास करें।

+0

धन्यवाद। मैंने 'low = high // 2' और 'low = 10 ** (len (str (x))/n) के साथ' low = high/2' को बदल दिया' '' कम = 10 ** (लेन (str (x))) // एन) '। यह 2.6 के नियमित प्रदर्शन के साथ 2.6 के प्रदर्शन को '__future__ आयात प्रभाग से' के साथ लाया। दुर्भाग्यवश 3.1 का प्रदर्शन अपरिवर्तित था - अभी भी 2.6 गुना धीमा है। – user200783

+0

बेशक, समस्या यह है कि पायथन 3 में "पूर्णांक" पाइथन 2 के पुराने "लंबे" हैं। ऑपरेटर यहां कोई फर्क नहीं पड़ता :) –

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