StringIOを文字列バッファーとして使用すると、listをバッファーとして使用するよりも遅くなります。
StringIOはいつ使用されますか?
from io import StringIO
def meth1(string):
a = []
for i in range(100):
a.append(string)
return ''.join(a)
def meth2(string):
a = StringIO()
for i in range(100):
a.write(string)
return a.getvalue()
if __== '__main__':
from timeit import Timer
string = "This is test string"
print(Timer("meth1(string)", "from __main__ import meth1, string").timeit())
print(Timer("meth2(string)", "from __main__ import meth2, string").timeit())
結果:
16.7872819901
18.7160351276
速度を測定する場合は、cStringIO
を使用する必要があります。
docs から:
モジュールcStringIOは、StringIOモジュールと同様のインターフェースを提供します。 StringIO.StringIOオブジェクトの頻繁な使用は、代わりにこのモジュールのStringIO()関数を使用することにより、より効率的にすることができます。
しかし、StringIOのポイントはファイルのようなオブジェクトであり、何かがそのようなものを期待し、実際のファイルを使用したくない場合です。
編集:from io import StringIO
なので、おそらくPython> = 3または少なくとも2.6。Py3では個別のStringIOとcStringIOがなくなりました。io.StringIOを提供するためにどの実装を使用したかはわかりません。 io.BytesIO
も。
StringIOの主な利点は、ファイルが予想される場所で使用できることです。だからあなたは例えばすることができます(Python 2)の場合:
import sys
import StringIO
out = StringIO.StringIO()
sys.stdout = out
print "hi, I'm going out"
sys.stdout = sys.__stdout__
print out.getvalue()
まあ、それを「バッファ」として使用して呼び出すかどうかはわかりません。2つの複雑な方法で文字列を100倍するだけです。簡単な方法を次に示します。
def meth3(string):
return string * 100
テストに追加する場合:
if __== '__main__':
from timeit import Timer
string = "This is test string"
# Make sure it all does the same:
assert(meth1(string) == meth3(string))
assert(meth2(string) == meth3(string))
print(Timer("meth1(string)", "from __main__ import meth1, string").timeit())
print(Timer("meth2(string)", "from __main__ import meth2, string").timeit())
print(Timer("meth3(string)", "from __main__ import meth3, string").timeit())
ボーナスとしてはるかに高速であることがわかりました:
21.0300650597
22.4869811535
0.811429977417
文字列の束を作成してから結合したい場合は、meth1()が正しい方法です。これをStringIOに書き込む意味はありません。これはまったく異なるものです。つまり、ファイルのようなストリームインターフェイスを持つ文字列です。