文字列の連結に+を決して使用してはならないという仮定ではなく、常に '' .joinを使用するというのは神話かもしれません。を使用+
すると、不変の文字列オブジェクトの不要な一時コピーが作成されますが、引用されていないその他の事実は、join
として、ループは一般にのオーバーヘッドを追加しますfunction call
。あなたの例を見てみましょう。
2つのリストを作成します。1つはリンクされたSO質問から、もう1つはより大きな偽造品からです
>>> myl1 = ['A','B','C','D','E','F']
>>> myl2=[chr(random.randint(65,90)) for i in range(0,10000)]
二つの機能を作成し、することができますUseJoin
し、UsePlus
それぞれの使用するjoin
と+
機能性を。
>>> 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)]
最初のリストでtimeitを実行しましょう
>>> 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
>>>
ランタイムはほとんど同じです。
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}
また、Joinを使用すると、不要な関数呼び出しが発生し、オーバーヘッドが増える可能性があります。
質問に戻ります。1は使用落胆すべきである+
オーバーjoin
すべてのケースありますか?
いいえ、考えなければなりません
- 問題のストリングの長さ
- 連結操作はありません。
そして、開発の時期尚早な最適化のオフコースは悪です。