2011-01-19 126 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是沒有意義的,它是完全不同的東西,即具有類似文件流接口的字符串。

相關問題