2011-01-19 327 views
40

使用StringIO作为字符串缓冲区比使用列表缓冲区慢。什么时候使用StringIO?

什么时候使用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 
+1

你可能是指“什么时候”而不是“以上”? – 2011-01-19 10:16:58

回答

23

如果测量速度,你应该使用cStringIO

docs

模块cStringIO提供类似于 StringIO的模块的 接口。大量使用 通过改用此模块中的函数 来代替StringIO.StringIO对象可以使 效率更高。

但StringIO的点是成为类文件对象,因为当一些希望这样,你不希望使用实际文件。

编辑:我注意到你使用from io import StringIO,所以你可能在Python> = 3或至少2.6。单独的StringIO和cStringIO在Py3中消失了。不知道他们用什么实现来提供io.StringIO。也有io.BytesIO

+0

用`cStringIO`尝试。结果:列表:17,cString:33. – user225312 2011-01-19 09:59:17

+3

io.StringIO是C实现,如果它存在于您的平台上。如果不是,它使用Python实现回退。之所以比较慢,是因为他在做一些他并不需要StringIO的东西。 – 2011-01-19 10:14:25

31

StringIO的主要优点是它可以用于需要文件的地方。所以,你可以做例子:

import sys 
import StringIO 

out = StringIO.StringIO() 

sys.stdout = out 

print "hi, I'm going out" 

sys.stdout = sys.__stdout__ 

print out.getvalue() 
17

好了,我不知道如果我想调用使用它作为一个“缓冲区”,你只是乘以一个字符串的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是没有意义的,它是完全不同的东西,即具有类似文件流接口的字符串。

相关问题