我搜索并搜索了这些缓冲模块之间的区别。然而,我仍然不太明白,我认为我读到的一些帖子已经过时了。
在Python2.7.11中,我使用r = requests.get(url)下载了一个特定格式的二进制文件。然后,我将StringIO.StringIO(r.content)、cStringIO.StringIO(r.content)和io.BytesIO(r.content)传递给一个为解析内容而设计的函数。
这三种方法都是可用的。我的意思是,即使文件是二进制的,使用StringIO仍然是可行的。为什么?
另一件事是有关他们的效率。
In [1]: import StringIO, cStringIO, io
In [2]: from numpy import random
In [3]: x = random.random(1000000)
In [4]: %timeit y = cStringIO.StringIO(x)
1000000 loops, best of 3: 736 ns per loop
In [5]: %timeit y = StringIO.StringIO(x)
1000 loops, best of 3: 283 µs per loop
In [6]: %timeit y = io.BytesIO(x)
1000 loops, best of 3: 1.26 ms per loop如上面所示,cStringIO > StringIO > BytesIO。
我发现有人提到io.BytesIO总是做一个新的副本,这需要花费更多的时间。但也有一些帖子提到,这在以后的Python版本中得到了修正。
因此,在最新的Python2.x和3.x中,有人能对这些IO进行彻底的比较吗?
我发现的一些参考资料:
但是cStringIO.StringIO('abc')不会引发任何错误。
这个帖子在2014年有一个补丁。
下面是Eric示例的Python2.7结果
%timeit cStringIO.StringIO(u_data)
1000000 loops, best of 3: 488 ns per loop
%timeit cStringIO.StringIO(b_data)
1000000 loops, best of 3: 448 ns per loop
%timeit StringIO.StringIO(u_data)
1000000 loops, best of 3: 1.15 µs per loop
%timeit StringIO.StringIO(b_data)
1000000 loops, best of 3: 1.19 µs per loop
%timeit io.StringIO(u_data)
1000 loops, best of 3: 304 µs per loop
# %timeit io.StringIO(b_data)
# error
# %timeit io.BytesIO(u_data)
# error
%timeit io.BytesIO(b_data)
10000 loops, best of 3: 77.5 µs per loop至于2.7,cStringIO.StringIO和StringIO.StringIO的效率远远高于io。
发布于 2016-05-26 14:01:22
您应该使用io.StringIO处理unicode对象,使用io.BytesIO处理python 2和3中的bytes对象,以实现向前兼容性(这是所有3项必须提供的)。
下面是一个更好的测试(针对python 2和3),它不包括从numpy到str/bytes的转换成本
import numpy as np
import string
b_data = np.random.choice(list(string.printable), size=1000000).tobytes()
u_data = b_data.decode('ascii')
u_data = u'\u2603' + u_data[1:] # add a non-ascii character然后:
import io
%timeit io.StringIO(u_data)
%timeit io.StringIO(b_data)
%timeit io.BytesIO(u_data)
%timeit io.BytesIO(b_data)在python 2中,还可以测试:
import StringIO, cStringIO
%timeit cStringIO.StringIO(u_data)
%timeit cStringIO.StringIO(b_data)
%timeit StringIO.StringIO(u_data)
%timeit StringIO.StringIO(b_data)其中一些会崩溃,抱怨非ascii角色。
Python3.5结果:
>>> %timeit io.StringIO(u_data)
100 loops, best of 3: 8.61 ms per loop
>>> %timeit io.StringIO(b_data)
TypeError: initial_value must be str or None, not bytes
>>> %timeit io.BytesIO(u_data)
TypeError: a bytes-like object is required, not 'str'
>>> %timeit io.BytesIO(b_data)
The slowest run took 6.79 times longer than the fastest. This could mean that an intermediate result is being cached
1000000 loops, best of 3: 344 ns per loopPython2.7结果(在另一台机器上运行):
>>> %timeit io.StringIO(u_data)
1000 loops, best of 3: 304 µs per loop
>>> %timeit io.StringIO(b_data)
TypeError: initial_value must be unicode or None, not str
>>> %timeit io.BytesIO(u_data)
TypeError: 'unicode' does not have the buffer interface
>>> %timeit io.BytesIO(b_data)
10000 loops, best of 3: 77.5 µs per loop>>> %timeit cStringIO.StringIO(u_data)
UnicodeEncodeError: 'ascii' codec cant encode character u'\u2603' in position 0: ordinal not in range(128)
>>> %timeit cStringIO.StringIO(b_data)
1000000 loops, best of 3: 448 ns per loop
>>> %timeit StringIO.StringIO(u_data)
1000000 loops, best of 3: 1.15 µs per loop
>>> %timeit StringIO.StringIO(b_data)
1000000 loops, best of 3: 1.19 µs per loophttps://stackoverflow.com/questions/37462075
复制相似问题