Apakah ada metode gabungan string massa efisien dalam Python (seperti StringBuilder di C # atau StringBuffer di Jawa)? Saya menemukan metode berikut di sini :
- Rangkaian sederhana menggunakan
+
- Menggunakan daftar string dan
join
metode - Menggunakan
UserString
dariMutableString
modul - Menggunakan array karakter dan
array
modul - Menggunakan
cStringIO
dariStringIO
modul
Tetapi apa yang Anda gunakan atau sarankan oleh para ahli, dan mengapa?
f''
format string yang akan lebih cepat daripada alternatif apa pun di versi Python sebelumnya.Jawaban:
Anda mungkin tertarik pada ini: Anekdot optimisasi oleh Guido. Meskipun perlu diingat juga bahwa ini adalah artikel lama dan mendahului keberadaan hal-hal seperti
''.join
(walaupun saya kirastring.joinfields
kurang lebih sama)Pada kekuatan itu,
array
modul mungkin paling cepat jika Anda dapat memperbaiki masalah Anda ke dalamnya. Tetapi''.join
mungkin cukup cepat dan memiliki manfaat menjadi idiomatis dan dengan demikian lebih mudah bagi programmer python lain untuk mengerti.Akhirnya, aturan emas optimasi: jangan optimalkan kecuali Anda tahu Anda perlu, dan mengukur daripada menebak.
Anda dapat mengukur berbagai metode menggunakan
timeit
modul. Itu bisa memberi tahu Anda mana yang tercepat, bukan orang asing acak di internet yang membuat tebakan.sumber
.join()
? Pertanyaan utamanya adalah, apakah itu a) membuat salinan string untuk penggabungan (mirip dengans = s + 'abc'
), yang membutuhkan O (n) runtime, atau b) cukup menambahkan ke string yang ada tanpa membuat salinan, yang membutuhkan O (1) ?''.join(sequenceofstrings)
adalah apa yang biasanya bekerja paling baik - paling sederhana dan tercepat.sumber
''.join(sequence)
ungkapan itu. Ini sangat berguna untuk menghasilkan daftar yang dipisahkan koma:', '.join([1, 2, 3])
memberikan string'1, 2, 3'
."".join(chr(x) for x in xrange(65,91))
--- dalam kasus ini, argumen untuk bergabung adalah iterator, dibuat melalui ekspresi generator. Tidak ada daftar sementara yang dibangun.Python 3.6 mengubah permainan untuk penggabungan string dari komponen yang diketahui dengan Literal String Interpolasi .
Diberikan kasus uji dari jawaban mkoistinen , memiliki string
Para pesaing adalah
f'http://{domain}/{lang}/{path}'
- 0,151 μs'http://%s/%s/%s' % (domain, lang, path)
- 0,321 μs'http://' + domain + '/' + lang + '/' + path
- 0,356 μs''.join(('http://', domain, '/', lang, '/', path))
- 0,249 µs (perhatikan bahwa membuat tupel panjang konstan sedikit lebih cepat daripada membuat daftar panjang konstan).Dengan demikian saat ini kode terpendek dan terindah yang mungkin juga tercepat.
Dalam versi alpha dari Python 3.6 implementasi
f''
string adalah yang paling lambat mungkin - sebenarnya kode byte yang dihasilkan cukup setara dengan''.join()
kasus dengan panggilan yang tidak perlustr.__format__
yang tanpa argumen hanya akan mengembalikanself
tidak berubah. Inefisiensi ini ditangani sebelum 3,6 final.Kecepatan dapat dikontraskan dengan metode tercepat untuk Python 2, yang merupakan
+
penggabungan pada komputer saya; dan itu membutuhkan 0,203 μs dengan string 8-bit, dan 0,259 μs jika semua string adalah Unicode.sumber
Itu tergantung pada apa yang Anda lakukan.
Setelah Python 2.5, penggabungan string dengan operator + cukup cepat. Jika Anda hanya menggabungkan beberapa nilai, menggunakan + operator bekerja paling baik:
Namun, jika Anda menyusun string dalam satu lingkaran, Anda lebih baik menggunakan metode penggabungan daftar:
... tetapi perhatikan bahwa Anda harus mengumpulkan string yang relatif tinggi sebelum perbedaannya terlihat.
sumber
Sesuai jawaban John Fouhy, jangan mengoptimalkan kecuali Anda harus, tetapi jika Anda di sini dan mengajukan pertanyaan ini, itu mungkin karena Anda harus melakukannya . Dalam kasus saya, saya perlu mengumpulkan beberapa URL dari variabel string ... cepat. Saya perhatikan tidak seorang pun (sejauh ini) tampaknya mempertimbangkan metode format string, jadi saya pikir saya akan mencobanya dan, sebagian besar untuk minat ringan, saya pikir saya akan melemparkan operator interpolasi string di sana untuk pengukuran yang baik. Sejujurnya, saya tidak berpikir salah satu dari ini akan menumpuk ke operasi '+' langsung atau '' .join (). Tapi coba tebak? Pada sistem Python 2.7.5 saya, operator interpolasi string mengatur semuanya dan string.format () adalah yang berkinerja terburuk:
Hasil:
Jika saya menggunakan domain yang lebih pendek dan jalur yang lebih pendek, interpolasi masih menang. Perbedaannya lebih jelas, dengan string yang lebih panjang.
Sekarang saya memiliki skrip pengujian yang bagus, saya juga menguji dengan Python 2.6, 3.3 dan 3.4, inilah hasilnya. Dalam Python 2.6, operator plus adalah yang tercepat! Pada Python 3, bergabunglah menang. Catatan: tes ini sangat berulang pada sistem saya. Jadi, 'plus' selalu lebih cepat di 2.6, 'intp' selalu lebih cepat di 2.7 dan 'join' selalu lebih cepat di Python 3.x.
Pelajaran yang dipelajari:
tl; dr:
sumber
f'http://{domain}/{lang}/{path}'
.format()
memiliki tiga bentuk, dalam urutan dari cepat untuk lambat:"{}".format(x)
,"{0}".format(x)
,"{x}".format(x=x)
itu cukup banyak tergantung pada ukuran relatif dari string baru setelah setiap penggabungan baru. Dengan
+
operator, untuk setiap rangkaian string baru dibuat. Jika string perantara relatif panjang, maka+
menjadi semakin lambat karena string perantara baru disimpan.Pertimbangkan kasus ini:
Hasil
1 0,00493192672729
2 0,000509023666382
3 0,00042200088501
4 0,000482797622681
Dalam kasus 1 & 2, kami menambahkan string besar, dan bergabung () melakukan sekitar 10 kali lebih cepat. Dalam kasus 3 & 4, kami menambahkan string kecil, dan '+' berkinerja sedikit lebih cepat
sumber
Saya mengalami situasi di mana saya perlu memiliki string yang tidak dapat ditambahkan ukurannya. Ini adalah hasil benchmark (python 2.7.3):
Ini tampaknya menunjukkan bahwa '+ =' adalah yang tercepat. Hasil dari tautan skymind agak ketinggalan zaman.
(Saya menyadari bahwa contoh kedua tidak lengkap, daftar akhir perlu digabungkan. Namun, ini menunjukkan, bahwa hanya menyiapkan daftar memakan waktu lebih lama daripada string concat.)
sumber
Satu Tahun kemudian, mari kita coba jawaban mkoistinen dengan python 3.4.3:
Tidak ada yang berubah. Bergabung masih merupakan metode tercepat. Dengan intp menjadi pilihan terbaik dalam hal keterbacaan, Anda mungkin ingin menggunakan intp.
sumber
Terinspirasi oleh tolok ukur @ JasonBaker, inilah yang sederhana membandingkan 10
"abcdefghijklmnopqrstuvxyz"
string, menunjukkan itu.join()
lebih cepat; bahkan dengan peningkatan kecil dalam variabel:Catenation
Ikuti
sumber
Untuk set kecil dari string pendek (yaitu 2 atau 3 string tidak lebih dari beberapa karakter), ditambah masih cara yang lebih cepat. Menggunakan skrip mkoistinen yang luar biasa dalam Python 2 dan 3:
Jadi ketika kode Anda melakukan sejumlah besar rangkaian kecil terpisah, plus adalah cara yang disukai jika kecepatan sangat penting.
sumber
Mungkin "f-string baru dengan Python 3.6" adalah cara yang paling efisien untuk merangkai string.
Menggunakan% s
Menggunakan .format
Menggunakan f
Sumber: https://realpython.com/python-f-strings/
sumber