【发布时间】:2023-04-11 10:18:01
【问题描述】:
我已经用谷歌搜索并在 SO 上搜索这些缓冲区模块之间的区别。不过,我还是不太明白,我觉得我看的一些帖子已经过时了。
在 Python 2.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 版本中已修复。
那么,任何人都可以在最新的 Python 2.x 和 3.x 中对这些 IOs 进行彻底的比较吗?
我找到的一些参考资料:
-
https://trac.edgewall.org/ticket/12046
io.StringIO 需要一个 unicode 字符串。 io.BytesIO 需要一个字节字符串。 StringIO.StringIO 允许 unicode 或字节字符串。 cStringIO.StringIO 需要一个被编码为字节字符串的字符串。
但cStringIO.StringIO('abc') 不会引发任何错误。
-
https://review.openstack.org/#/c/286926/1
StringIO 类是错误的,特别是考虑到子单元 v2 是二进制而不是字符串。
-
http://comments.gmane.org/gmane.comp.python.devel/148717
cStringIO.StringIO(b'data') 没有复制数据,而 io.BytesIO(b'data') 复制了数据(即使以后没有修改数据)。
2014 年这篇文章中有一个修复补丁。
- 这里没有列出很多 SO 帖子。
这是 Eric 示例的 Python 2.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。
【问题讨论】:
-
你能把你的每个 sn-ps 标记为 python 2 还是 python 3 吗?
-
@Eric,我在 Python 2.7.11 中完成了所有测试。好像
(c)StringIO在3中被io替换了,我主要用2.7。但我认为其他读者讨论这两个版本会很有意义。 -
io也在 python 2 中
标签: python stringio bytesio cstringio