L'assunto che non si dovrebbe mai, mai usare + per la concatenazione di stringhe, ma invece usare sempre '' .join può essere un mito. È vero che l'utilizzo di +
crea copie temporanee non necessarie di oggetto stringa immutabile, ma l'altro fatto non frequentemente citato è che chiamare join
in un ciclo generalmente aggiungerebbe il sovraccarico di function call
. Prendiamo il tuo esempio.
Creare due liste, una dal legata domanda SO e un altro una più grande fabbricato
>>> myl1 = ['A','B','C','D','E','F']
>>> myl2=[chr(random.randint(65,90)) for i in range(0,10000)]
Creiamo due funzioni, UseJoin
e UsePlus
di utilizzare la rispettiva funzionalità join
e +
.
>>> def UsePlus():
return [myl[i] + myl[i + 1] for i in range(0,len(myl), 2)]
>>> def UseJoin():
[''.join((myl[i],myl[i + 1])) for i in range(0,len(myl), 2)]
Consente di eseguire timeit con il primo elenco
>>> myl=myl1
>>> t1=timeit.Timer("UsePlus()","from __main__ import UsePlus")
>>> t2=timeit.Timer("UseJoin()","from __main__ import UseJoin")
>>> print "%.2f usec/pass" % (1000000 * t1.timeit(number=100000)/100000)
2.48 usec/pass
>>> print "%.2f usec/pass" % (1000000 * t2.timeit(number=100000)/100000)
2.61 usec/pass
>>>
Hanno quasi la stessa fase di esecuzione.
Consente di utilizzare Cprofile
>>> myl=myl2
>>> cProfile.run("UsePlus()")
5 function calls in 0.001 CPU seconds
Ordered by: standard name
ncalls tottime percall cumtime percall filename:lineno(function)
1 0.001 0.001 0.001 0.001 <pyshell#1376>:1(UsePlus)
1 0.000 0.000 0.001 0.001 <string>:1(<module>)
1 0.000 0.000 0.000 0.000 {len}
1 0.000 0.000 0.000 0.000 {method 'disable' of '_lsprof.Profiler' objects}
1 0.000 0.000 0.000 0.000 {range}
>>> cProfile.run("UseJoin()")
5005 function calls in 0.029 CPU seconds
Ordered by: standard name
ncalls tottime percall cumtime percall filename:lineno(function)
1 0.015 0.015 0.029 0.029 <pyshell#1388>:1(UseJoin)
1 0.000 0.000 0.029 0.029 <string>:1(<module>)
1 0.000 0.000 0.000 0.000 {len}
1 0.000 0.000 0.000 0.000 {method 'disable' of '_lsprof.Profiler' objects}
5000 0.014 0.000 0.014 0.000 {method 'join' of 'str' objects}
1 0.000 0.000 0.000 0.000 {range}
e sembra che l'uso di aderire, si traduce in chiamate di funzione non necessarie che potrebbero aggiungere alla testa.
Ora tornando alla domanda. Si dovrebbe scoraggiare l'uso di +
su join
in tutti i casi?
Credo di no, le cose dovrebbero essere prese in considerazione
- lunghezza della stringa in questione
- No di concatenazione di funzionamento.
E fuori rotta in uno sviluppo l'ottimizzazione pre-matura è malvagia.
Il suo più ordinato e si ha un maggiore controllo per non fare la concatenazione. Ma la sua battuta di corda è leggermente più lenta: P –
Stai dicendo che '+' è più veloce o più lento? E perché? – Taymon
+ è più veloce, 'In [2]:% timeit "a" * 80 + "b" * 80' ' 1000000 loop, migliore di 3: 356 ns per loop' 'In [3]:% timeit "% s% s"% ("a" * 80, "b" * 80) ' ' 1000000 cicli, meglio di 3: 907 ns per ciclo' –