Come per la risposta di John Fouhy, non lo fanno ottimizzare meno che non bisogna, ma se siete qui e fare questa domanda, potrebbe essere proprio perché si deve . Nel mio caso, avevo bisogno di assemblare alcuni URL da variabili stringa ... velocemente. Ho notato che nessuno (finora) sembra prendere in considerazione il metodo del formato di stringa, quindi ho pensato di provarlo e, soprattutto per un lieve interesse, ho pensato di lanciare l'operatore di interpolazione delle stringhe per un buon misuratore. Ad essere sincero, non pensavo che nessuno di questi si sarebbe impilato in un'operazione diretta '+' o in '' .join (). Ma indovina un po? Sul mio sistema Python 2.7.5, l'operatore di interpolazione delle stringhe le governa tutte e string.format () è il peggiore:
# 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), ))
I risultati:
# 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)
Se uso un dominio più breve e un percorso più breve, l'interpolazione vince comunque. La differenza è più pronunciata, tuttavia, con stringhe più lunghe.
Ora che ho avuto un bel test script, ho anche testato in Python 2.6, 3.3 e 3.4, ecco i risultati. In Python 2.6, l'operatore plus è il più veloce! Su Python 3, l'adesione vince. Nota: questi test sono molto ripetibili sul mio sistema. Quindi, 'plus' è sempre più veloce su 2.6, 'intp' è sempre più veloce su 2.7 e 'join' è sempre più veloce su Python 3.x.
# 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)
Lezione imparata:
- A volte, i miei presupposti sono completamente sbagliati.
- Test contro il sistema env. sarai in esecuzione in produzione.
- L'interpolazione delle stringhe non è ancora morta!
tl; dr:
- Se si utilizza 2.6, utilizzare l'operatore +.
- se stai usando 2.7 usa l'operatore '%'.
- se stai usando 3.x usa '' .join ().