SORU
21 ŞUBAT 2013, PERŞEMBE


Neden Python3 hiçbir xrange fonksiyonu var mı?

Son zamanlarda Python3 kullanmaya başladım ve xrange eksikliği kullanıcısı acıyor.

Basit bir örnek:

1)Python2:

from time import time as t
def count():
  st = t()
  [x for x in xrange(10000000) if x%4 == 0]
  et = t()
  print et-st
count()

2)Python3:

from time import time as t

def xrange(x):

    return iter(range(x))

def count():
    st = t()
    [x for x in xrange(10000000) if x%4 == 0]
    et = t()
    print (et-st)
count()

Sonuçlar, sırasıyla:

1)1.53888392448 2)3.215819835662842

Bu yüzden mi? Neden xrange alındı? Öğrenmek için harika bir araçtır. Yeni başlayanlar, benim gibi, hepimiz bir noktada gibi. Neden kaldırmak? Birisi uygun PEP bana gelin, ben bulamıyorum.

Şerefe.

CEVAP
22 ŞUBAT 2013, Cuma


Bazı performans ölçümleri, elle time ile yapmaya çalışmak yerine timeit kullanarak.

İlk olarak, Apple 2.7.2 64-bit:

In [37]: %timeit collections.deque((x for x in xrange(10000000) if x%4 == 0), maxlen=0)
1 loops, best of 3: 1.05 s per loop

Şimdi, 3.3.0 64-bit python.org :

In [83]: %timeit collections.deque((x for x in range(10000000) if x%4 == 0), maxlen=0)
1 loops, best of 3: 1.32 s per loop

In [84]: %timeit collections.deque((x for x in xrange(10000000) if x%4 == 0), maxlen=0)
1 loops, best of 3: 1.31 s per loop

In [85]: %timeit collections.deque((x for x in iter(range(10000000)) if x%4 == 0), maxlen=0) 
1 loops, best of 3: 1.33 s per loop

, 3 anlaşılan.x range gerçekten biraz 2 yavaştır.x 13**. Ve OP xrange fonksiyonu ile bir ilgisi yok. (Şaşırtıcı değil, bir kerelik arama için __iter__ yuvası değil ihtimali görünür arasında 10000000 çağrıları ne olursa olsun döngü, ama birisi söyleyene kadar bir ihtimal.)

Ama sadece 0 daha yavaş. Nasıl OP yavaş olarak 2x aldın? Ben 32-bit Python ile aynı testleri tekrar olursa, 1.58 vs 3.12. Benim tahminim, bu henüz o durumda başka bir yerde 3 olmasıdır.x 64-bit 32-bit zarar bu şekilde performans için optimize edilmiştir.

Ama ne önemi var? , 3.3.0 64-bit ile tekrar deneyin

In [86]: %timeit [x for x in range(10000000) if x%4 == 0]
1 loops, best of 3: 3.65 s per loop

Yani, list binanın iki kat daha uzun tekrarında ise tamamı daha alır.

Ve gelince "çok ", tahlilleri, 3.görünüşe göre Python 2.6 daha fazla kaynak tüketir x range tam olarak 2 ile aynı boyutta.x 19**—ve büyük olarak 10x olsa bile, gereksiz bir listesi bina hala dizi yineleme yapabileceği bir şey daha bir sorun hakkında daha fazla 10000000x.

Ve deque içinde C döngüsü yerine ** 20 açık bir döngüye ne dersiniz?

In [87]: def consume(x):
   ....:     for i in x:
   ....:         pass
In [88]: %timeit consume(x for x in range(10000000) if x%4 == 0)
1 loops, best of 3: 1.85 s per loop

Yani, neredeyse kadar zaman range yineleme gerçek iş olarak for deyimi boşa.

Eğer dizi bir nesne yineleme optimize endişe ediyorsanız, muhtemelen yanlış yerde arıyorsunuz.


Bu arada, neden sorup duruyorsun xrange çıkarılmış olursa olsun, kaç kez daha söyle aynı şeyi, ama ederim tekrar tekrar: değildi kaldırıldı: değiştirildi range ve 2.x range ne kaldırıldı.

İşte 3.3 range nesne 2 doğrudan soyundan olduğunu kanıtlayın.x xrange nesne (ve 2.x range fonksiyon): 3.3 range 2.7 xrange kaynak. Hatta change history görebilirsiniz (sanırım bu dize son örneği "xrange" dosyada herhangi bir yere). yerini değiştirmek için bağlı

Neden yavaş?

İlk olarak, yeni bir çok özellik eklediler. Diğer minör yan etkileri olan her yerde değişiklikler (özellikle yineleme içerde) her türlü yaptılar. Ve bir sürü iş olunca biraz daha az önemli durumlarda pessimizes bile önemli ölçüde çeşitli önemli davaları optimize etmek için vardı. Bu tüm kadar ekleyin ve range mümkün olduğunca hızlı yineleme şimdi biraz daha yavaş olduğunu şaşırmadım. Kimse yeterince odaklanmak ister bundan daha az önemli, o durumlardan biri. Kimse bu performans farkı kodlarına sıcak olduğu gerçek hayattan bir senaryo olması muhtemeldir.

Bunu Paylaş:
  • Google+
  • E-Posta
Etiketler:

YORUMLAR

SPONSOR VİDEO

Rastgele Yazarlar

  • jat4011

    jat4011

    16 EKİM 2010
  • Numberphile

    Numberphile

    15 EYLÜL 2011
  • Videogamerz | Call of Duty

    Videogamerz

    5 NİSAN 2012