2015-04-11 20 views
10

a ve b dahil olmak üzere rastgele bir tam sayı seçmek istiyorum.Seçimin performansı vs randint

Bunu yapmanın 3 yolunu biliyorum. Ancak bunların performansı çok sezgilere görünüyor:

benim makinede
import timeit 

t1 = timeit.timeit("n=random.randint(0, 2)", setup="import random", number=100000) 
t2 = timeit.timeit("n=random.choice([0, 1, 2])", setup="import random", number=100000) 
t3 = timeit.timeit("n=random.choice(ar)", setup="import random; ar = [0, 1, 2]", number=100000) 

[print(t) for t in [t1, t2, t3]] 

, bu verir:

0.29744589625620965 
0.19716156798482648 
0.17500512311108346 

bir online interpreter kullanarak, bu verir:

0.23830216699570883 
0.16536146598809864 
0.15081614299560897 

Not nasıl en direkt Yaptığım şeyi yapmak için özel işlev kullanan sürüm (# 1), % 50 daha kötü olduğunu önceden tanımlayan en tuhaf sürümdür (# 3). bir dizi ve daha sonra rasgele seçer.

Neler oluyor?

+0

t1 karşılaştırmayı deneyin, t2 ve t3 seçeneği ile (aralık (3)) 've cevap açık olmalıdır. – Shashank

+0

't2' ve' t3' aynıdır, ancak 't2'de listenin oluşturulmasını ölçüyorsunuz ve' t3'de yapmazsınız. – Jens

+0

@Jens Bir seferde birkaç sayı üretecekseniz, t2' önemlidir, "t3" çok fazla sayıya ihtiyacınız olacağını bildiğiniz durumlarda biraz zaman kazandırır. – Superbest

cevap

5

Sadece uygulama ayrıntıları. randint delege randrange için, bu nedenle başka bir işlev çağrısı ek yük katmanı vardır ve randrange bir çok argüman denetimi ve diğer kaba geçiyor. Buna karşılık, choice gerçekten basit bir tek astardır.

def randint(self, a, b): 
    return self.randrange(a, b+1) 

def randrange(self, start, stop=None, step=1, _int=int, _maxwidth=1L<<BPF): 
    istart = _int(start) 
    if istart != start: 
     # not executed 
    if stop is None: 
     # not executed 

    istop = _int(stop) 
    if istop != stop: 
     # not executed 
    width = istop - istart 
    if step == 1 and width > 0: 
     if width >= _maxwidth: 
      # not executed 
     return _int(istart + _int(self.random()*width)) 

Ve burada kod yolu choice geçer var: Burada

kod yolu randint dışarı ve yorumlardan arındırılmış uygulanmayan kodla, bu çağrı için geçer var

def choice(self, seq): 
    return seq[int(self.random() * len(seq))] 
+2

Ayrıca, her ikisi için de farkın sabit olduğunu unutmayın. '[0, 1, 2]' yerine '' aralığı (10000) 'kullanarak ve' randint (0, 10000) 'yapmak temelde küçük örnek için olduğu gibi aynı zaman alır. Yani, temel olarak, tanımladığınız yük, 'seçim' seçeneğinden 'randint' değerini 0,0000012 saniye daha yavaş yapar (seçim setinizi önceden tanımlayabileceğinizi varsayar). Bu büyük bir anlaşma değil. Ancak, t2'den kaçınılmalıdır, çünkü listenin oluşturulmasını da zamanlamaktadır ve bu yüzden büyük listelerle yavaşlayacaktır. – BrenBarn

+0

@BrenBarn Yalnızca bir tuple kullanıyorsanız, kullanım yükünden kaçınabilirsiniz. – Veedrac

İlgili konular