53

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 __name__ == '__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
4

4 に答える 4

35

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()
于 2011-01-19T09:51:57.443 に答える
27

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

ドキュメントから:

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

ただし、StringIOのポイントは、ファイルのようなオブジェクトにすることです。これは、何かがそのようなことを予期していて、実際のファイルを使用したくない場合に使用します。

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

于 2011-01-19T09:51:42.893 に答える
18

さて、それを「バッファ」として使用して呼び出したいかどうかはわかりません。2つの複雑な方法で文字列を100倍するだけです。簡単な方法は次のとおりです。

def meth3(string):
    return string * 100

それをテストに追加すると、次のようになります。

if __name__ == '__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に書き込む意味はありません。これは、まったく異なるもの、つまりファイルのようなストリームインターフェイスを備えた文字列です。

于 2011-01-19T10:10:14.230 に答える
-1

LennartRegebroアプローチに基づく別のアプローチ。これはリストメソッド(meth1)よりも高速です

def meth4(string):
    a = StringIO(string * 100)
    contents = a.getvalue()
    a.close()
    return contents

if __name__ == '__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())
    print(Timer("meth3(string)", "from __main__ import meth3, string").timeit())
    print(Timer("meth4(string)", "from __main__ import meth4, string").timeit())

結果(秒):

meth1 = 7.731315963647944

meth2 = 9.609279402186985

meth3 = 0.26534052061106195

meth4 = 2.915035489152274

于 2018-03-14T05:57:03.670 に答える