Setler ve dikmeler farklı kullanım durumları için optimize edilmiştir. Bir kümenin birincil kullanımı, sipariş agnostik olan hızlı üyelik testidir. Dikte için, arama maliyeti en kritik işlemdir ve anahtarın bulunması daha olasıdır. Kümelerde, bir öğenin varlığı veya yokluğu önceden bilinmemektedir ve bu nedenle küme uygulamasının hem bulunan hem de bulunmayan durum için optimize etmesi gerekir. Ayrıca, birleşim ve kavşak gibi yaygın küme işlemleri için yapılan bazı optimizasyonlar, performansı düşürmeden küme sırasını korumayı zorlaştırır.
Her iki veri yapısı da karma tabanlı olsa da, kümelerin sadece null değerlere sahip diktler olarak uygulanması yaygın bir yanlış anlamadır. HattaCPython 3.6'daki kompakt dict uygulamasından önce , set ve dict uygulamaları çok az kod kullanımıyla zaten önemli ölçüde farklıydı. Örneğin, dikteler rastgele problama kullanır, ancak kümeler önbellek yerini iyileştirmek için doğrusal problama ve açık adresleme kombinasyonunu kullanır. İlk doğrusal prob ( CPython'da varsayılan 9 adım ), bir dizi bitişik anahtar / karma çiftini kontrol edecek ve karma çarpışma işleme maliyetini azaltarak performansı artıracaktır - ardışık bellek erişimi dağınık problardan daha ucuzdur.
dictobject.c
- usta , v3.5.9
setobject.c
- usta , v3.5.9
- issue18771 - Python 3.4'te ayarlanan nesneler için karma çarpışmaların maliyetini azaltmak için değişiklik kümesi.
Olurdu mümkün kompakt dict benzer olması CPython seti uygulamasını değiştirme teoride ama pratikte dezavantajları vardır ve önemli çekirdek geliştiricileri böyle bir değişiklik yapılmasına karşı çıktı.
Setler sırasız kalır. (Neden? Kullanım şekilleri farklı. Ayrıca, farklı uygulamalar.)
- Guido van Rossum
Kümeler, kampanya siparişini korumak için uygun olmayan farklı bir algoritma kullanır. Set-to-set işlemleri, sipariş gerekiyorsa esnekliklerini ve optimizasyonlarını kaybeder. Küme matematiği sıralı olmayan kümeler olarak tanımlanır. Kısacası, set siparişi yakın gelecekte değil.
- Raymond Hettinger
3.7 için setlerin sıkıştırılıp sıkıştırılmayacağı ve neden karar verildiğine ilişkin cevaplar hakkında ayrıntılı bir tartışma, python-dev posta listelerinde bulunabilir.
Özetle, ana hususlar kullanım şekillerinin farklı olmasıdır (** kwargs gibi ekleme sipariş dikmeleri faydalıdır , kümeler için daha azdır), sıkıştırma kümeleri için alan tasarrufu daha az önemlidir (çünkü yalnızca anahtar ve karma dizisi vardır) tuşların, karmaların ve değerlerin aksine yoğunlaştırma) ve setlerde yukarıda belirtilen doğrusal problama optimizasyonu kompakt bir uygulama ile uyumsuzdur.
Raymond'un aşağıda en önemli noktaları kapsayan gönderisini yeniden oluşturacağım.
14 Eylül 2016, 15:50, Eric Snow şunu yazdı:
Sonra, setlere de aynısını yapacağım.
Yanlış anlamadığım sürece, Raymond sette benzer bir değişiklik yapmaya karşıydı.
Doğru. İşte insanlar vahşi çalışmaya başlamadan önce konu hakkında birkaç düşünce.
Kompakt dikte için, alan tasarrufu, endeksler tarafından tüketilen ek alan ve anahtar / değer / hash dizilerinin aşırı konumlandırılması, anahtar / değer / hash dizilerinin gelişmiş yoğunluğu ile dengelenmekten daha fazla olan net bir kazançtı. Ancak kümeler için net çok daha az elverişliydi, çünkü hala endekslere ve aşırı konumlandırmaya ihtiyacımız var, ancak alan maliyetini sadece üç diziden sadece ikisini yoğunlaştırarak dengeleyebiliriz. Diğer bir deyişle, anahtarlar, değerler ve karmalar için yer harcadığınızda sıkıştırma yapmak daha mantıklıdır. Eğer bu üçünden birini kaybederseniz, zorlayıcı olmaktan çıkıyor.
Setler için kullanım şekli dikteden farklıdır. İlki daha fazla hit ya da özledim aramaları var. İkincisi daha az eksik anahtar aramasına sahip olma eğilimindedir. Ayrıca, set-to-set işlemleri için yapılan bazı optimizasyonlar, performansı etkilemeden set sırasını korumayı zorlaştırır.
Ayarlanan performansı iyileştirmek için alternatif bir yol izledim. Sıkıştırmak yerine (çok fazla alan kazanmak değildi ve ek bir dolaylamanın maliyetine katlandı), çarpışmaların maliyetini azaltmak ve önbellek performansını artırmak için doğrusal problama ekledim. Bu gelişme sözlükler için savunduğum sıkıştırma yaklaşımıyla uyumsuz.
Şimdilik, sözlükler üzerindeki sipariş yan etkisi garanti edilmemektedir, bu nedenle setlerin de sipariş edilmesinde ısrar etmeye başlamak erken. Dokümanlar zaten bir OrderedSet ( https://code.activestate.com/recipes/576694/ ) oluşturmak için bir tarife bağlanıyor,
ancak alım neredeyse sıfır gibi görünüyor. Ayrıca, Eric Snow bize hızlı bir OrderedDict verdiğine göre, MutableSet ve OrderedDict'ten bir OrderedSet oluşturmak her zamankinden daha kolay, ancak yine de gerçek bir ilgi görmedim çünkü tipik set-set veri analizi gerçekte değil sipariş ihtiyacı veya bakım. Benzer şekilde, hızlı üyelik testlerinin birincil kullanımı düzen agnostiktir.
Bununla birlikte, PyPI'ye alternatif set uygulamaları eklemek için yer olduğunu düşünüyorum. Özellikle, set-to-set işlemlerin tüm anahtar aralıkları karşılaştırılarak hızlandırılabileceği verilerle ilgili bazı ilginç özel durumlar vardır (bkz.
Https://code.activestate.com/recipes/230113-implementation-of-
başlangıç noktası için kümeler kullanarak sıralama listeleri ). IIRC, PyPI zaten set benzeri çiçek filtreleri ve guguk karma için koda sahiptir.
Python çekirdeğinde büyük bir kod bloğunun kabul edilmesinin heyecan verici olduğunu, ancak garanti edilmediğinden emin olmadıkça, taşkınların diğer veri türlerinin daha büyük yeniden yazmalarına katılmaya açılmaması gerektiğini anlıyorum.
- Raymond Hettinger
Gönderen [Python-Dev] Python 3.6 dict kompakt hale gelir ve özel bir versiyon alır; ve anahtar kelimeler sipariş edildi , Eylül 2016.