8

最速のメソッドを使用できるように、Python で文字列メソッドをプロファイリングする方法です。ファイル、StringIO、StringIO、および通常の文字列で文字列連結をテストするためのこのコードがあります。

#!/usr/bin/env python
#title           : pythonTiming.py
#description     : Will be used to test timing function in python
#author          : myusuf
#date            : 19-11-2014
#version         : 0
#usage           :python pythonTiming.py
#notes           :
#python_version  :2.6.6  
#==============================================================================

import time
import cStringIO
import StringIO

class Timer(object):

    def __enter__(self):
        self.start = time.time()
        return self

    def __exit__(self, *args):
        self.end = time.time()
        self.interval = self.end - self.start

testbuf = """ Hello This is a General String that will be repreated
This string will be written to a file , StringIO and a sregualr strin then see the best to handle string according to time 

""" * 1000

MyFile = open("./testfile.txt" ,"wb+")
MyStr  = ''
MyStrIo = StringIO.StringIO()
MycStrIo = cStringIO.StringIO()

def strWithFiles():
    global MyFile
    print "writing string to file "
    for index in range(1000):
        MyFile.write(testbuf) 
    pass

def strWithStringIO():
    global MyStrIo
    print "writing string to StrinIO "
    for index in range(1000):
        MyStrIo.write(testbuf)

def strWithStr():
    global MyStr
    print "Writing String to STR "
    for index in range(500):
        MyStr =  MyStr +  testbuf

def strWithCstr():
    global MycStrIo
    print "writing String to Cstring"
    for index in range(1000):
        MycStrIo.write(testbuf)

with Timer() as t:
    strWithFiles()
print('##Request took %.03f sec.' % t.interval)

with Timer() as t:                                                                                
    strWithStringIO()
print('###Request took %.03f sec.' % t.interval)  

with Timer() as t:                                                                                
    strWithCstr()
print('####Request took %.03f sec.' % t.interval)  

with Timer() as t:
    read1 = 'x' + MyFile.read(-1)
print('file read ##Request took %.03f sec.' % t.interval)

with Timer() as t:
    read2 = 'x' + MyStrIo.read(-1)
print('stringIo read ###Request took %.03f sec.' % t.interval)

with Timer() as t:
    read3 = 'x' + MycStrIo.read(-1)
print('CString read ####Request took %.03f sec.' % t.interval)




MyFile.close()
  1. Python のドキュメント サイトでは、それcStringIOよりも高速であると書かれてStringIOいますが、結果ではStringIO連結のパフォーマンスが優れているとされていますが、なぜでしょうか?

  2. 一方、ファイルの実装を読んでCにいるので、からの読み取りは(ファイルに似た動作)cStringIOよりも高速ですが、なぜ文字列連結が遅いのですか?StringIOcStringIO

  3. これらの方法よりも高速に文字列を処理する方法はありますか?

4

1 に答える 1

13

パフォーマンスが向上する理由StringIOは、書き込まれたすべての文字列のリストを保持し、必要な場合にのみ結合するためです。したがって、書き込み操作は、オブジェクトをリストに追加するのと同じくらい簡単です。ただし、cStringIOモジュールにはこの余裕がなく、各文字列のデータをバッファーにコピーし、必要に応じてバッファーのサイズを変更する必要があります (これにより、大量のデータを書き込むときに冗長なデータのコピーが作成されます)。

より大きな文字列をたくさん書いているので、これは がStringIO行う作業が に比べて少ないことを意味しcStringIOます。書き込み先のオブジェクトから読み取る場合StringIO、そのサイズのバッファーを事前に割り当てて、オブジェクトに書き込まれた文字列の長さの合計を計算することにより、必要なコピーの量を最適化できます。

ただし、StringIO一連の文字列を結合する最速の方法ではありません。これは、追加機能 (バッファーのさまざまな部分をシークし、そこにデータを書き込む) を提供するためです。この機能が必要ない場合は、リスト文字列を結合するだけでstr.join済みます。

joined_string = "".join(testbuf for index in range(1000))
# or building the list of strings to join separately
strings = []
for i in range(1000):
    strings.append(testbuf)
joined_string = "".join(strings)
于 2015-02-20T22:19:22.850 に答える