Saya mencoba untuk menghapus karakter yang tidak diinginkan dari string tertentu menggunakan text.translate()
Python 3.4.
Kode minimalnya adalah:
import sys
s = 'abcde12345@#@$#%$'
mapper = dict.fromkeys(i for i in range(sys.maxunicode) if chr(i) in '@#$')
print(s.translate(mapper))
Ini bekerja seperti yang diharapkan. Namun program yang sama ketika dijalankan dengan Python 3.4 dan Python 3.5 memberikan perbedaan yang besar.
Kode untuk menghitung pengaturan waktu adalah
python3 -m timeit -s "import sys;s = 'abcde12345@#@$#%$'*1000 ; mapper = dict.fromkeys(i for i in range(sys.maxunicode) if chr(i) in '@#$'); " "s.translate(mapper)"
Program Python 3.4 membutuhkan 1,3ms sedangkan program yang sama dengan Python 3.5 hanya membutuhkan 26,4μs .
Apa yang telah ditingkatkan dalam Python 3.5 yang membuatnya lebih cepat dibandingkan dengan Python 3.4?
python
string
python-3.x
python-internals
python-3.5
Bhargav Rao
sumber
sumber
dict.fromkeys(ord(c) for c in '@#$')
?Jawaban:
TL; DR - MASALAH 21118
Cerita yang panjang
Josh Rosenberg menemukan bahwa
str.translate()
fungsinya sangat lambat dibandingkan denganbytes.translate
, dia mengangkat masalah , menyatakan bahwa:Mengapa
str.translate()
lambat?Alasan utama untuk
str.translate()
menjadi sangat lambat adalah karena pencariannya menggunakan kamus Python.Penggunaan
maketrans
memperburuk masalah ini. Pendekatan serupa menggunakanbytes
membangun larik C yang terdiri dari 256 item untuk pencarian tabel cepat. Karenanya penggunaan Python level yang lebih tinggidict
membuatstr.translate()
dalam Python 3.4 sangat lambat.Apa yang terjadi sekarang?
Pendekatan pertama adalah menambahkan patch kecil, translate_writer , Namun peningkatan kecepatannya tidak begitu menyenangkan. Segera patch lain fast_translate diuji dan menghasilkan hasil yang sangat bagus dengan speedup hingga 55%.
Perubahan utama seperti yang dapat dilihat dari file ini adalah pencarian kamus Python diubah menjadi pencarian tingkat C.
Kecepatannya sekarang hampir sama dengan
bytes
Catatan kecil di sini adalah bahwa peningkatan kinerja hanya menonjol dalam string ASCII.
Seperti yang disebutkan JFSebastian dalam komentar di bawah, Before 3.5, translate digunakan untuk bekerja dengan cara yang sama untuk kasus ASCII dan non-ASCII. Namun dari kasus 3.5 ASCII jauh lebih cepat.
Sebelumnya ASCII vs non-ascii biasanya hampir sama, namun sekarang kita dapat melihat perubahan besar dalam performanya.
Ini bisa menjadi peningkatan dari 71,6μs menjadi 2,33μs seperti yang terlihat dalam jawaban ini .
Kode berikut menunjukkan ini
Tabulasi hasil:
sumber
55
%: seperti yang ditunjukkan oleh jawaban Anda, kecepatannya bisa1000
s% .python3.5 -m timeit -s "text = 'mJssissippi'*100; d=dict(J='i')" "text.translate(d)"
(ascii) vs.python3.5 -m timeit -s "text = 'm\U0001F602ssissippi'*100; d={'\U0001F602': 'i'}" "text.translate(d)"
(non-ascii). Yang terakhir ini jauh (10x) lebih lambat..translate()
yaitu, kasus ascii jauh lebih cepat di Python 3.5 saja (Anda tidak perlubytes.translate()
performanya di sana).