John Fouhy'nin cevabına göre, gerekmedikçe optimizasyon yapmayın, ancak buradaysanız ve bu soruyu soruyorsanız, bunun nedeni tam olarak zorunda olmanız olabilir . Benim durumumda, dize değişkenlerinden bazı URL'leri bir araya getirmem gerekiyordu ... hızlı. Hiç kimse (şimdiye kadar) dize biçimi yöntemi düşünüyor gibi görünüyor, bu yüzden ben bunu denemek düşündüm ve çoğunlukla hafif ilgi için, ben orada iyi ölçüm için orada dize enterpolasyon operatörü atmak düşündüm. Dürüst olmak gerekirse, bunların ikisinin de doğrudan bir '+' operasyonuna ya da bir '' .join () biriktireceğini düşünmemiştim. Ama tahmin et ne oldu? Python 2.7.5 sistemimde, dize enterpolasyon operatörü hepsini yönetir ve string.format () en kötü performanstır:
# concatenate_test.py
from __future__ import print_function
import timeit
domain = 'some_really_long_example.com'
lang = 'en'
path = 'some/really/long/path/'
iterations = 1000000
def meth_plus():
'''Using + operator'''
return 'http://' + domain + '/' + lang + '/' + path
def meth_join():
'''Using ''.join()'''
return ''.join(['http://', domain, '/', lang, '/', path])
def meth_form():
'''Using string.format'''
return 'http://{0}/{1}/{2}'.format(domain, lang, path)
def meth_intp():
'''Using string interpolation'''
return 'http://%s/%s/%s' % (domain, lang, path)
plus = timeit.Timer(stmt="meth_plus()", setup="from __main__ import meth_plus")
join = timeit.Timer(stmt="meth_join()", setup="from __main__ import meth_join")
form = timeit.Timer(stmt="meth_form()", setup="from __main__ import meth_form")
intp = timeit.Timer(stmt="meth_intp()", setup="from __main__ import meth_intp")
plus.val = plus.timeit(iterations)
join.val = join.timeit(iterations)
form.val = form.timeit(iterations)
intp.val = intp.timeit(iterations)
min_val = min([plus.val, join.val, form.val, intp.val])
print('plus %0.12f (%0.2f%% as fast)' % (plus.val, (100 * min_val / plus.val), ))
print('join %0.12f (%0.2f%% as fast)' % (join.val, (100 * min_val / join.val), ))
print('form %0.12f (%0.2f%% as fast)' % (form.val, (100 * min_val / form.val), ))
print('intp %0.12f (%0.2f%% as fast)' % (intp.val, (100 * min_val / intp.val), ))
Sonuçlar:
# python2.7 concatenate_test.py
plus 0.360787868500 (90.81% as fast)
join 0.452811956406 (72.36% as fast)
form 0.502608060837 (65.19% as fast)
intp 0.327636957169 (100.00% as fast)
Daha kısa bir etki alanı ve daha kısa bir yol kullanırsam enterpolasyon yine de kazanır. Fark daha uzun dizelerle daha belirgindir.
Şimdi güzel bir test senaryom vardı, Python 2.6, 3.3 ve 3.4 altında da test ettim, işte sonuçlar. Python 2.6'da, artı operatör en hızlısıdır! Python 3'te birleştirme kazanır. Not: Bu testler sistemimde çok tekrarlanabilir. Yani, 'artı' her zaman 2.6'da daha hızlı, 'intp' her zaman 2.7'de daha hızlı ve 'katıl' her zaman Python 3.x'te daha hızlıdır.
# python2.6 concatenate_test.py
plus 0.338213920593 (100.00% as fast)
join 0.427221059799 (79.17% as fast)
form 0.515371084213 (65.63% as fast)
intp 0.378169059753 (89.43% as fast)
# python3.3 concatenate_test.py
plus 0.409130576998 (89.20% as fast)
join 0.364938726001 (100.00% as fast)
form 0.621366866995 (58.73% as fast)
intp 0.419064424001 (87.08% as fast)
# python3.4 concatenate_test.py
plus 0.481188605998 (85.14% as fast)
join 0.409673971997 (100.00% as fast)
form 0.652010936996 (62.83% as fast)
intp 0.460400978001 (88.98% as fast)
# python3.5 concatenate_test.py
plus 0.417167026084 (93.47% as fast)
join 0.389929617057 (100.00% as fast)
form 0.595661019906 (65.46% as fast)
intp 0.404455224983 (96.41% as fast)
Ders öğrenildi:
- Bazen varsayımlarım yanlıştır.
- Sisteme karşı test env. üretimde koşacaksınız.
- Dize enterpolasyonu henüz ölmedi!
tl; dr:
- 2.6 kullanıyorsanız + işlecini kullanın.
- 2.7 kullanıyorsanız '%' operatörünü kullanın.
- 3.x kullanıyorsanız '' .join () kullanın.