Python 什么时候使用StringIO,而不是加入字符串列表?

Python 什么时候使用StringIO,而不是加入字符串列表?,python,stringio,Python,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.wri

使用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

如果测量速度,应使用
cStringIO

从:

cStringIO模块提供一个 接口类似于 StringIO模块。大量使用 StringIO。可以创建StringIO对象 使用该函数可提高效率 而不是此模块中的StringIO()

但是StringIO的要点是成为一个类似文件的对象,因为当某些东西需要这样的对象时,您不想使用实际的文件


编辑:我注意到您使用的是来自io导入StringIO的
,因此您可能使用的Python>=3或至少是2.6。单独的StringIO和cStringIO在Py3中消失了。不确定他们使用什么实现来提供io.StringIO。还有
io.BytesIO

StringIO的主要优点是可以在需要文件的地方使用。例如,您可以执行以下操作(对于Python 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是没有意义的,它是完全不同的,即具有类似文件的流接口的字符串。

另一种基于Lennart Regebro方法的方法。 这比列表方法(meth1)快

结果(第节):

meth1=7.731315963647944

meth2=9.609279402186985

meth3=0.2653405206106195

meth4=2.915035489152274


cStringIO
试试。结果:List:17,cString:33.io.StringIO是一个C实现,如果您的平台上存在的话。如果不是,则使用Python实现回退。它变慢的原因是因为他正在做一些他一开始就不需要StringIO的事情。你是说上面的“When”而不是“Where”吗?试试meth1和列表理解。它可以在python 2中与
一起使用吗?从我这里看到的不:@Mr_和Mrs_D请看哪一个状态将从2.5开始工作。你还想要什么,上面有血D@MarkLawrence:不,它不会-重新阅读您链接的注释-您必须滚动您自己的上下文管理器我不认为在
StringIO
中包装字符串有任何用处,只是立即将其再次转换回字符串并丢弃
StringIO
对象,特别是如果您关心运行时。
21.0300650597
22.4869811535
0.811429977417
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())