Python cStringIO的编写时间比StringIO花费更多的时间(执行字符串方法)

Python cStringIO take more time than StringIO in writing (performance of string methods)

以我的方式在python中分析字符串方法,以便可以使用最快的方法。
我有这段代码可以测试文件,StringIO,StringIO和普通字符串中的字符串连接。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
#!/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()
  • 尽管Python文档站点说cStringIOStringIO快,但是结果说StringIO在串联中具有更好的性能,为什么?

  • 另一方面,当我读取文件的实现并且cStringIO在C语言中时,从cStringIO读取要比StringIO快(其行为与file相似),那么为什么字符串连接速度很慢?

  • 还有没有其他方法可以比这些方法更快地处理字符串?


  • StringIO性能更好的原因是在幕后,它只是保留已写入其中的所有字符串的列表,并且仅在必要时组合它们。因此,写操作就像将对象附加到列表一样简单。但是,cStringIO模块不具备这种功能,必须将每个字符串的数据复制到其缓冲区中,并在必要时调整其缓冲区的大小(在写入大量数据时会创建很多冗余的数据复制)。

    由于您正在编写许多较大的字符串,因此与cStringIO相比,这意味着StringIO要做的工作更少。从已写入的StringIO对象读取数据时,它可以通过计算写入该字符串的字符串的长度总和来优化所需的复制量,从而预先分配该大小的缓冲区。

    但是,StringIO并不是连接一系列字符串的最快方法。这是因为它提供了其他功能(查找缓冲区的不同部分并在其中写入数据)。如果不需要此功能,只需将列表字符串连接在一起,则str.join是最快的方法。

    1
    2
    3
    4
    5
    6
    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)