2013-02-27 20 views
8

için 'random.random' anahtar sözcüğün argümanı olarak kullanıldığında `random.shuffle 'ifadesinin kısa süreli çalışma süresi Python3 kullanırken, random.shuffle ile bir listenin karıştırılmasının, çalışma zamanı için random.random işlevini açıkça gönderdiğinde çalışma zamanının yaklaşık yarısına ihtiyaç duyduğunu gözlemledim. random anahtar kelime tartışması. Python2'nin aynı soruna sahip olup olmadığını kontrol ettim ancak sadece Python3 ile gerçekleştiğini tespit ettim.Python3

İki versiyonlarının çalışma zamanı ölçmek için şu kodu kullanın: Eğer Python3 ve Python2 ile aynı kod ile görmek için

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)) 

Ben testcase at ideone yaptı. documentation for shuffle aynı işlevi random.random Ben opsiyonel anahtar kelime argümanı random ihmal varsayılan durumda kullanılır, bu yüzden bunu varsayılan durumda olduğu gibi rastgele sayı oluşturmak için aynı işlevi verirken hiçbir fark olmamalıdır göre

.

ben Lib/random.py klasörlerde shuffle fonksiyon için ilgili kaynaklar (Python3 vs Python2) kontrol edildi ve onlar açıkça random anahtar kelime için bir işlevle Python3 sürümünü çağırmak eğer aynı şekilde davranması bulundu. Bu argümanı çıkarırsam Python3, _randbelow yardımcı işlevini kullanır, bu yüzden benim sorunumun kökü olmalı. Python3'ün neden _randbelow kullandığını anlayamıyorum çünkü shuffle'u yavaşlatıyor. Anladığım kadarıyla, faydası rasgele büyük rasgele sayıların üretilmesinde yatar, ama 2^32 elementten (100000 benim durumumda) daha az olan bir listeyi karıştırmamı yavaşlatmamalı. Onlar birbirine yaklaştırır ben Python3 kullandığınızda olmalıdır rağmen çalışma zamanları böyle bir fark görüyorum neden

kimse bana açıklayabilir?

P.S .: Python2 ile çalışma süresinin neden Python3'ten daha iyi olduğunu, ancak Python3'te argüman rand=rand.rand argümanını kullanırken çalışma zamanındaki farkı sadece Python3'te kullanmama nedenleriyle ilgilenmiyorum.

cevap

4

fonksiyonu random.shuffle içinde docstring'ini kodu ile çelişmektedir.

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] 

Ama Python 3.2 buluruz:: docstringe 2.7.2+ python'da doğrudur

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] 

Yani docstring'ini hala eski hikaye anlatır, ama şimdi kullanılan varsayılan işlevi rastgele .randbelow