2013-02-27 23 views
8

में कीवर्ड तर्क के रूप में 'random.random` का उपयोग करते समय मैंने देखा कि Python3 का उपयोग करते समय random.shuffle के साथ किसी सूची की शफ़लिंग को लगभगफ़ंक्शन को स्पष्ट रूप से सबमिट करने के दौरान लगभग आधे रनटाइम की आवश्यकता होती है random कीवर्ड तर्क। मैंने जांच की कि क्या Python2 में एक ही समस्या है लेकिन पाया कि यह केवल Python3 के साथ होता है।'random.ruffle` का छोटा रनटाइम' Python3

मैं दो संस्करणों के क्रम को मापने के लिए निम्नलिखित कोड का उपयोग करें:

from timeit import Timer 
t1 = Timer("random.shuffle(l)", "import random; l = list(range(100000))") 
t2 = Timer("random.shuffle(l, random = random.random)", "import random; l = list(range(100000))") 
print("With default rand: %s" % t1.repeat(10,1)) 
print("With custom rand: %s" % t2.repeat(10,1)) 

मैं एक testcase at ideone बनाया आप python3 और Python2 के साथ एक ही कोड के साथ देखने के लिए।

documentation for shuffle एक ही समारोह random.random डिफ़ॉल्ट मामले में प्रयोग किया जाता है जब मैं वैकल्पिक कीवर्ड तर्क random छोड़ देते हैं, तो कोई फर्क नहीं है जब मैं यह एक ही समारोह डिफ़ॉल्ट मामले में यादृच्छिक संख्या उत्पन्न करने के लिए देना नहीं होना चाहिए के अनुसार

मैं Lib/random.py फ़ोल्डर में shuffle समारोह के लिए संबंधित स्रोतों (को Python2 बनाम python3) की जाँच की और पाया कि वे उसी तरह अगर मैं स्पष्ट रूप से random कीवर्ड के लिए एक समारोह के साथ python3 संस्करण फोन व्यवहार करते हैं। अगर मैं इस तर्क को छोड़ देता हूं, तो Python3 सहायक कार्य _randbelow का उपयोग करता है, इसलिए मेरी समस्या के लिए रूट होना चाहिए। मैं नहीं देख सकता कि क्यों Python3 _randbelow का उपयोग करता है क्योंकि यह shuffle धीमा हो जाता है। जहां तक ​​मैं इसे समझता हूं, इसका लाभ मनमाने ढंग से बड़ी यादृच्छिक संख्याओं को उत्पन्न करने में निहित है, लेकिन यह उस सूची की मेरी शफलिंग को धीमा नहीं करना चाहिए जिसमें 2^32 तत्वों (मेरे मामले में 100000) से कम रास्ता है।

क्या कोई मुझे बता सकता है कि मुझे रनटाइम में इतना अंतर क्यों दिख रहा है, हालांकि जब मैं पायथन 3 का उपयोग करता हूं तो उन्हें एक साथ होना चाहिए?

पीएस .: कृपया ध्यान दें कि मुझे कोई दिलचस्पी नहीं है कि पाइथन 2 के साथ रनटाइम क्यों पाइथन 3 के मुकाबले बेहतर है, लेकिन पाइथन 3 बनाम तर्क rand=rand.rand तर्क का उपयोग करते समय रनटाइम में अंतर केवल पायथन 3 में इसका उपयोग नहीं कर रहा है।

उत्तर

4

फ़ंक्शन random.shuffle फ़ंक्शन में डॉकस्ट्रिंग कोड का विरोध करता है। अजगर में 2.7.2+ docstring सही है:

def shuffle(self, x, random=None, int=int): 
    """x, random=random.random -> shuffle list x in place; return None. 

    Optional arg random is a 0-argument function returning a random 
    float in [0.0, 1.0); by default, the standard random.random. 
    """ 

    if random is None: 
     random = self.random 
    for i in reversed(xrange(1, len(x))): 
     # pick an element in x[:i+1] with which to exchange x[i] 
     j = int(random() * (i+1)) 
     x[i], x[j] = x[j], x[i] 

लेकिन अजगर 3.2 में हम पाते हैं:

def shuffle(self, x, random=None, int=int): 
    """x, random=random.random -> shuffle list x in place; return None. 

    Optional arg random is a 0-argument function returning a random 
    float in [0.0, 1.0); by default, the standard random.random. 
    """ 

    randbelow = self._randbelow 
    for i in reversed(range(1, len(x))): 
     # pick an element in x[:i+1] with which to exchange x[i] 
     j = randbelow(i+1) if random is None else int(random() * (i+1)) 
     x[i], x[j] = x[j], x[i] 

तो docstring अभी भी पुरानी कहानी कहता है, लेकिन अब डिफ़ॉल्ट इस्तेमाल किया समारोह यादृच्छिक है .andandow