2011-01-19 25 views
40

StringIO'yu string buffer olarak kullanmak, arabellek olarak kullanmaktan daha yavaştır.StringIO ne zaman kullanılır?

StringIO ne zaman kullanılır?

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

Sonuçlar: Hız için ölçmek ise

16.7872819901 
18.7160351276 
+1

Yukarıda "Nerede" yerine "Ne Zaman" anlamına gelebilir? –

cevap

23

, sen cStringIO kullanmalıdır. docs kaynaktan

:

cStringIO StringIO modülünün benzer bir arayüz sağlar modülü. StringIO.StringIO nesnelerinin ağır kullanımı bu modülden StringIO() işlevini kullanarak daha verimli hale getirilebilir.

Ama StringIO noktası şey böyle bekler zaman için bir file benzeri bir nesne, olmaktır ve asıl dosyaları kullanmak istemiyoruz.

Edit:from io import StringIO kullandığınızı farkettim, bu yüzden muhtemelen Python> = 3 veya en az 2.6. Ayrı StringIO ve cStringIO Py3'te gitti. Io.StringIO'yu sağlamak için hangi uygulamaları kullandıklarından emin değil. io.BytesIO da var.

+0

"cStringIO" ile deneyin. Sonuçlar: Liste: 17, cString: 33. – user225312

+3

io.StringIO, platformunuzda varsa, bir C uygulamasıdır. Eğer değilse, bir Python uygulaması geri dönüşü kullanır. Daha yavaş olmasının nedeni, ilk etapta StringIO'ya ihtiyaç duymadığı bir şey yapıyor olmasıdır. –

31

StringIO'nun ana avantajı, bir dosyanın beklendiği yerde kullanılabilir olmasıdır. Yani örneğin yapabilirsiniz:

import sys 
import StringIO 

out = StringIO.StringIO() 

sys.stdout = out 

print "hi, I'm going out" 

sys.stdout = sys.__stdout__ 

print out.getvalue() 
+0

Python 2'de "with" ile kullanılabilir mi? Burada gördüğüm kadarıyla: http://bugs.python.org/issue1286 –

+0

@Mr_and_Mrs_D lütfen bkz. [Http://bugs.python.org/issue1286#msg176512](http://bugs.python.org/issue1286 # msg176512) hangi 2,5 yukarı çalışacağını belirtir. Daha ne istiyorsun, kanıyor mu? : D –

+0

@MarkLawrence: hayır bunu yapmaz - bağladığınız yorumu tekrar gözden geçirin - verdiğim bağlantıyı kendi içerik yöneticisi –

17

Eh, çağırmak istiyorum eğer bilmiyorum olarak kullanan bir sadece iki karmaşık şekillerde, bir dizgi 100 kez katlanarak artıyor, "tampon" . İşte bir komplikasyonsuz yoludur:

def meth3(string): 
    return string * 100 

biz testine olduğunu eklerseniz:

21.0300650597 
22.4869811535 
0.811429977417 

Eğer isterseniz:

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

Daha hızlı bir bonus olarak bir yol olarak çıkıyor bir demet dizeleri oluşturun ve sonra onlara katılın, meth1() doğru yoldur. Tamamen farklı bir şey olan, yani dosya benzeri bir akış arabirimine sahip bir dize olan StringIO'ya yazmanın bir anlamı yoktur.

İlgili konular