web-dev-qa-db-ja.com

文字列のリストを結合するのではなく、StringIOはいつ使用されますか?

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
48
simha

速度を測定する場合は、cStringIOを使用する必要があります。

docs から:

モジュールcStringIOは、StringIOモジュールと同様のインターフェースを提供します。 StringIO.StringIOオブジェクトの頻繁な使用は、代わりにこのモジュールのStringIO()関数を使用することにより、より効率的にすることができます。

しかし、StringIOのポイントはファイルのようなオブジェクトであり、何かがそのようなものを期待し、実際のファイルを使用したくない場合です。

編集:from io import StringIOなので、おそらくPython> = 3または少なくとも2.6。Py3では個別のStringIOとcStringIOがなくなりました。io.StringIOを提供するためにどの実装を使用したかはわかりません。 io.BytesIOも。

26
plundra

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()
32
TryPyPy

まあ、それを「バッファ」として使用して呼び出すかどうかはわかりません。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に書き込む意味はありません。これはまったく異なるものです。つまり、ファイルのようなストリームインターフェイスを持つ文字列です。

17
Lennart Regebro