TL; DR - SAYI 21118
Uzun hikaye
Josh Rosenberg, str.translate()
işlevin çok yavaş bytes.translate
olduğunu öğrendi, bir sorunu gündeme getirerek şunları söyledi:
Python 3'te, str.translate()
genellikle optimizasyon değil, bir performans pessimizasyonu söz konusudur.
Neden str.translate()
yavaştı?
str.translate()
Çok yavaş olmanın ana nedeni , aramanın bir Python sözlüğünde yapılmasıydı.
Kullanımı maketrans
bu sorunu daha da kötüleştirdi. bytes
Hızlı tablo araması için benzer yaklaşım kullanarak 256 öğelik bir C dizisi oluşturur. Dolayısıyla yüksek seviyeli Python kullanımı dict
yapar str.translate()
Python 3.4 çok yavaş.
Ne oldu şimdi?
İlk yaklaşım küçük bir yama eklemekti, translate_writer , Ancak hız artışı o kadar da hoş değildi. Yakında başka bir yama fast_translate test edildi ve% 55'e varan hızlanma ile çok güzel sonuçlar verdi.
Dosyadan görülebileceği gibi ana değişiklik, Python sözlük aramasının bir C seviyesi aramasına dönüştürülmesidir.
Şimdi hızlar neredeyse aynı bytes
unpatched patched
str.translate 4.55125927699919 0.7898181750006188
str.translate from bytes trans 1.8910855210015143 0.779950579000797
Buradaki küçük bir not, performans geliştirmenin yalnızca ASCII dizelerinde öne çıkmasıdır.
JFSebastian'ın aşağıdaki bir yorumda bahsettiği gibi, 3.5'ten önce çeviri, hem ASCII hem de ASCII olmayan durumlarda aynı şekilde çalışıyordu. Ancak 3.5 ASCII durumundan çok daha hızlıdır.
Daha önceki ASCII ve non-ascii karşılaştırması eskiden neredeyse aynıydı, ancak şimdi performansta büyük bir değişiklik görebiliyoruz.
Bu görüldüğü gibi 2.33μs için 71.6μs gelen bir gelişme olabilir cevap .
Aşağıdaki kod bunu göstermektedir
python3.5 -m timeit -s "text = 'mJssissippi'*100; d=dict(J='i')" "text.translate(d)"
100000 loops, best of 3: 2.3 usec per loop
python3.5 -m timeit -s "text = 'm\U0001F602ssissippi'*100; d={'\U0001F602': 'i'}" "text.translate(d)"
10000 loops, best of 3: 117 usec per loop
python3 -m timeit -s "text = 'm\U0001F602ssissippi'*100; d={'\U0001F602': 'i'}" "text.translate(d)"
10000 loops, best of 3: 91.2 usec per loop
python3 -m timeit -s "text = 'mJssissippi'*100; d=dict(J='i')" "text.translate(d)"
10000 loops, best of 3: 101 usec per loop
Sonuçların çizelgesi:
Python 3.4 Python 3.5
Ascii 91.2 2.3
Unicode 101 117
dict.fromkeys(ord(c) for c in '@#$')
?