SORU
18 Mayıs 2010, Salı


Neden &dizesi bir nokta olduğunda quot;&; anahtar kelime farklı bir davranış " mı?

Bu kodu göz önünde bulundurun:

>>> x = "google"
>>> x is "google"
True
>>> x = "google.com"
>>> x is "google.com"
False
>>>

Neden böyle?

Yukarıdaki doğru olduğundan emin olmak için, sadece 2.5.4, 2.6.5, 2 Python üzerinde test ettik.7b2, Python, windows 3.1 ve Python 2.7b1 Linux üzerinde.

Hepsinin arasında tutarlılık var gibi görünüyor, tasarımı öyle. Bir şey mi kaçırdım?

Ben sadece o başarısız kişisel etki alanı filtreleme senaryomu bazıları.

CEVAP
18 Mayıs 2010, Salı


is nesne kimliğini doğrular ve değişmez türleri edebi karşılaşınca Python herhangi bir uygulama, tamamen ücretsizyabu değişmez, yazın yeni bir nesne yapmakyabu tür varolan nesneler, bazıları yeniden (aynı temel nesne için yeni bir başvuru ekleyerek) olup olmadığını görmek için arama. Bu optimizasyon pragmatik bir seçimdirdeğilkodunuzu hiç bir uygulama alabilir veren güveniyor yani anlamsal kısıtlamaları tabi, (veya Python hata düzeltme/iyileştirme sürümü ile kırılabilir!).

Örneğin düşünün:

>>> import dis
>>> def f():
...   x = 'google.com'
...   return x is 'google.com'
... 
>>> dis.dis(f)
  2           0 LOAD_CONST               1 ('google.com')
              3 STORE_FAST               0 (x)

  3           6 LOAD_FAST                0 (x)
              9 LOAD_CONST               1 ('google.com')
             12 COMPARE_OP               8 (is)
             15 RETURN_VALUE    

bu özel uygulama yanibir işlev içindesenin gözlem geçerli değildir ve yalnızca bir nesne değişmez (tam anlamıyla) ve gerçekten yaptı

>>> f()
True

Pragmatik çünkü içinde bir işlevi yapmak bir geçit yerel tablo sabitleri (kurtarmaya bellek tarafından değil yapma, birden çok sabit, değişmez nesneler nereden yeter) oldukça ucuz ve hızlı, ve Mayıs sunuyoruz iyi performans verir, çünkü işlevi çağrılabilir tekrar tekrar daha sonra.

Ama, aynı uygulamaetkileşimli komut satırına(Edit: Ben aslında bu da bir modülün en üst seviyede olacağını düşündüm, ama @Thomas tarafından bir yorum bana doğru, daha sonra bakın) ayarlayın:

>>> x = 'google.com'
>>> y = 'google.com'
>>> id(x), id(y)
(4213000, 4290864)

bellek kurtarmak için çalışırken rahatsız böyle idler farklı, yani, farklı nesneler DEĞİLDİR. Potansiyel olarak daha yüksek maliyet ve daha düşük döner vardır ve bu uygulama bu doktoru sezgisel arama rahatsız değil ve git söyle.

Editbir : modül üst düzey, @' gözlem, verilen örneğin: . başına Thomas

$ cat aaa.py
x = 'google.com'
y = 'google.com'
print id(x), id(y)

tekrar-sabitler tabanlı gördüğümüz tablo bu uygulama bellek optimizasyonu:

>>> import aaa
4291104 4291104

(sonu @Thomas' gözlem) başına Düzenleyin.

Son olarak, aynı uygulama yeniden:

>>> x = 'google'
>>> y = 'google'
>>> id(x), id(y)
(2484672, 2484672)

sezgisel farklı çünkü burada, değişmez dize "gibi görünüyor olabilir bir tanımlayıcı" -- yani olabilir kullanılan işlem gerektiren staj... yani iyileştirici stajyerler yine de (ve bir kez toplanarak arayan olur çok hızlı tabiki). Ve gerçekten de sürpriz sürpriz...:

>>> z = intern(x)
>>> id(z)
2484672

...xvardırinterned, bir süre önce gördüğünüz gibi, intern değeri geri döneraynıx 25 ** eskisi gibi y,) gibi nesne. Tabii, iyileştirici değil ya bu güvenmemelisinizvarbir şey otomatik olarak stajyer için, sadece bir optimizasyon sezgisel; interned string, intern bunları açıkça ihtiyacın olursa, sadece güvenli olması için. Sen ne zamanyapınstajyer dizeleri açıkça...:

>>> x = intern('google.com')
>>> y = intern('google.com')
>>> id(x), id(y)
(4213000, 4213000)

...sonra senyapınemin olun tamamen aynı nesne (yani, aynı id()) sonuçlar her zaman öylesine sen-ebilmek uygulamak mikro-optimizasyon gibi kontrol is yerine == (ben nadiren bulunan minik performans elde etmek için değer rahatsız;-).

Editsadece açıklığa kavuşturmak için, burada performans farklılıkları türden bahsediyorum, yavaş bir Macbook Air üzerinde...:

$ python -mtimeit -s"a='google';b='google'" 'a==b'
10000000 loops, best of 3: 0.132 usec per loop
$ python -mtimeit -s"a='google';b='google'" 'a is b'
10000000 loops, best of 3: 0.107 usec per loop
$ python -mtimeit -s"a='goo.gle';b='goo.gle'" 'a==b'
10000000 loops, best of 3: 0.132 usec per loop
$ python -mtimeit -s"a='google';b='google'" 'a is b'
10000000 loops, best of 3: 0.106 usec per loop
$ python -mtimeit -s"a=intern('goo.gle');b=intern('goo.gle')" 'a is b'
10000000 loops, best of 3: 0.0966 usec per loop
$ python -mtimeit -s"a=intern('goo.gle');b=intern('goo.gle')" 'a == b'
10000000 loops, best of 3: 0.126 usec per loop

...birkaç on her şekilde nanosaniye, en fazla. Yani, değmez biledüşünmeen uç kısmında tek "en [küfür silinmiş] [küfür silindi] bu performans düşüklüğü" durumu!-)

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

YORUMLAR

SPONSOR VİDEO

Rastgele Yazarlar

  • calicoJake

    calicoJake

    29 EKİM 2007
  • David Wills

    David Wills

    31 Aralık 2007
  • fufko

    fufko

    27 ŞUBAT 2006