【发布时间】:2014-10-24 05:05:25
【问题描述】:
我正在查看StringIO 的来源,上面写着一些注释:
- 使用真实文件通常更快(但不太方便)。
- C 中还有一个更快的实现,称为
cStringIO,但是 它不可子类化。
StringIO 就像一个内存文件对象,
为什么它比真正的文件对象慢?
【问题讨论】:
我正在查看StringIO 的来源,上面写着一些注释:
cStringIO,但是
它不可子类化。StringIO 就像一个内存文件对象,
为什么它比真正的文件对象慢?
【问题讨论】:
这不是实际上是关于 Python 的解释性质:BytesIO 在 Python* 中实现,与 StringIO 相同,但仍然优于文件 I/O。
事实上,StringIO 在StringIO 的理想用例(单次写入空缓冲区的开头)下比文件 I/O 快。实际上,如果写入足够大,它甚至会击败cStringIO。请参阅我的问题here。
那么为什么StringIO 被认为是“慢”? StringIO 的真正问题是得到不可变序列的支持,无论是str 还是unicode。如果你只写一次,这很好,很明显。但是,正如tdelaney's answer 对我的问题所指出的那样,它在写入随机位置时会减慢一吨(例如,10-100 倍),因为每次在中间写入时,它都必须复制整个支持序列。
BytesIO 没有这个问题,因为它由(可变的)bytearray 支持。同样,无论cStringIO 做什么,它似乎都更容易处理随机写入。我猜它在内部打破了不变性规则,因为 C 字符串是可变的。
* 无论如何,_pyio 中的版本是。 io 中的标准库版本是用 C 编写的。
【讨论】:
从源代码上看不一定很明显,但是 python 文件对象是直接构建在 C 库函数上的,可能有一小层 python 来呈现 python 类,甚至是 C 包装器来呈现 python 类。本机 C 库将被高度优化以从磁盘读取字节和块。 python StringIO 库都是原生 python 代码——比原生 C 代码慢。
【讨论】:
look through,而不是look for。
Python 的文件处理is implemented entirely in C。这意味着它的速度非常快(至少与原生 C 代码的数量级相同)。
但是,StringIO 库是用 Python 编写的。因此,模块本身会被解释,并带有相关的性能损失。
如您所知,还有另一个模块 cStringIO,带有 similar interface,您可以在对性能敏感的代码中使用它。 这不是子类的原因是因为它是用 C 编写的。
【讨论】: