普通のサイズなら+=で十分。listを育てて''.join(list)するのはナンセンス。
多少大きいなら、''.join([i for i in ジェネレータ])
本当に大きいなら、''.join(ジェネレータ)
ジェネレータをリスト内包表記でリストにしたほうが たいてい 速いというのは、意外な結果でした。
以下が検証につかったプログラムです。
from timeit import Timer #リストを育てて、join str_test1 = """ for num in _gen: str_list.append(num) _join(str_list) """ #stringIOに追記 str_test2 = """ for num in _gen: file_str.write(num) file_str.getvalue() """ #charのarrayに追加 str_test3 = """ for num in _gen: char_array.fromstring(num) char_array """ # += で 育てていく str_test4 = """ for num in _gen: out_str += num out_str """ # リスト内包表記をjoin str_test5 = """ ret = _join([i for i in _gen]) ret """ # ジェネレータを直にjoin str_test6 = """ ret = _join(_gen) ret """ setup = """ loop_count = 30 out_str = '' from array import array char_array = array('c') str_list = [] from cStringIO import StringIO file_str = StringIO() _join = ''.join _name = 'test' _gen=('<test' + ' name="' + _name + '"' + '>' + `num` + '</test>' for num in xrange(loop_count)) """ print Timer(str_test1, setup).repeat(3, 100) print Timer(str_test2, setup).repeat(3, 100) print Timer(str_test3, setup).repeat(3, 100) print Timer(str_test4, setup).repeat(3, 100) print Timer(str_test5, setup).repeat(3, 100) print Timer(str_test6, setup).repeat(3, 100)
loop_count=30
[0.00024053336528595537, 0.00023634288663743064, 0.00023606352260685526]
[0.00015420954332512338, 0.0001477841469750274, 0.00015532700490439311]
[8.7441281721112318e-005, 8.353016892215237e-005, 8.2692073192447424e-005]
[7.2076200012816116e-005, 6.7326993303140625e-005, 6.7885723183280788e-005]
[8.0177787822321989e-005, 7.5987310992786661e-005, 7.5707945143221878e-005]
[0.00047128894948400557, 0.00047352387082355563, 0.00047156831351458095]
# +=が一番速い!
# ''.join(ジェネレータ)は一番遅い!
loop_count=300
[0.0019653335821203655, 0.0020566859766404377, 0.0019753907254198566]
[0.00092833027701999526, 0.00092358107031031977, 0.00092413980019045994]
[0.00075568263673631009, 0.00067997468977409881, 0.00062019055440032389]
[0.00051794292267004494, 0.00050229847693117335, 0.00050257784096174873]
[0.00045676196350541431, 0.00043832386472786311, 0.00044111751776654273]
[0.00082524454956001136, 0.00080149851419264451, 0.0007970286733325338]
# ''.join(i for i in ジェネレータ)の順位が上昇。一番速い!
# ''.join(ジェネレータ)の順位が上昇。
loop_count=3000
[0.024607876141089946, 0.024106695123919053, 0.023980701458640397]
[0.017470097456680378, 0.019163050053975894, 0.021411380497738719]
[0.009339734519016929, 0.0092833027665619738, 0.0093380583293765085]
[0.0081722677041398128, 0.0050972958852071315, 0.0080621978486306034]
[0.0041698037039168412, 0.0040753782959654927, 0.0040725846429268131]
[0.0043092068972327979, 0.004270654510037275, 0.0042558481600281084]
# ''.join(ジェネレータ)が2位に。
loop_count=30000
[0.32366962840205815, 0.33386114715540316, 0.33299315974545607]
[0.19254905302113912, 0.19246356729672698, 0.19229231648205314]
[0.18879075413315149, 0.14344420869201713, 0.18765234128841257]
[0.13475986473167723, 0.16792050386175106, 0.1337812487345218]
[0.054552184705244144, 0.055729149933540612, 0.055441683231038041]
[0.046381872556594317, 0.05237118125478446, 0.052848616234768997]
# ''.join(ジェネレータ)が1位に。
# でも、''.join(i for i in ジェネレータ)とあんまり変わらない。なぜに?
loop_count=300000
[3.215461741645413, 3.1868516808699496, 3.1819172548475763]
[2.0470207805756218, 2.0494777967596747, 2.0539613274868316]
[16.015020065398858, 16.072113355188776, 16.03753214444987]
[15.98263103271529, 15.960840553758317, 15.985554309276267]
[0.47812361627075006, 0.46673641482448147, 0.48726667774826637]
[0.46456016057891247, 0.45079220962543332, 0.46201709993874829]
# += と char_array が、一番遅くなった。
0 件のコメント:
コメントを投稿