Python 2.x和3.x中的BufferedReader

2 投票
2 回答
2730 浏览
提问于 2025-04-16 09:02

我有一个程序可以在Python 2和Python 3中运行,但它们的速度差别非常大。我知道在这两个版本之间做了一些内部的改动,但在使用io.BufferedReader时,速度差异真的很明显。在这两个版本中,我都使用了io.BufferedReader,因为主程序循环只需要一次读取一个字节。以下是脚本的cProfile输出摘录(请看cumtime,而不是tottime):

Python 2:
 ncalls  tottime  percall  cumtime  percall filename:lineno(function)
 36984   0.188    0.000    0.545    0.000   io.py:929(read)

Python 3:
 36996    0.063   0.000    0.063    0.000   {method 'read' of '_io.BufferedReader' objects}

当我打印这个对象时,两个版本都返回类似io.BufferedReader的东西,所以我可以确定它们都在使用BufferedReader。

这里是相关的代码。请查看第28行。调用者负责设置bufstream。我使用了bufstream = io.open('testfile', 'rb')

为什么在读取文件中的单个字节时,BufferedReader的速度差别这么大?我该如何“修复”Python 2.x中的这个问题?我正在运行Python 2.6和Python 3.1。

2 个回答

4

使用2.7版本应该能解决这个问题。可以查看一下PEP 3116Python 2.7的文档

在2.6版本中,io模块的一部分是用Python写的,而在2.7及以上版本中,整个模块都是用C语言写的

6

要给你一个更完整的答案,我们需要看看你的代码(或者更好的是,给我们一个可以运行的代码简版)。

不过,从你的输出信息中,我们可以得到一些部分答案:io.py 表明“Python 2”(为了避免混淆,最好给出具体的版本号)是在用 Python 实现 BufferedReader,而 _io.BufferedReader 则表明“Python 3”是用 C 语言实现的。

最新消息:Python 2.6 的 io.py 文件超过 64Kb,开头有以下注释:

# This is a prototype; hopefully eventually some of this will be
# reimplemented in C.

Python 2.7 的 io.py 大约 4Kb,看起来是一个 _io 模块的简单封装。

如果你想要真正的帮助来解决 2.6 的问题,请展示你的代码。

可能的 Python 2.6 解决方法

不要这样写:

test = io.open('test.bmp', 'rb')

而是这样:

test = open('test.bmp', 'rb')

一些粗略的时间数据,包括缺失的链接(Python 2.7):

Windows 7 专业版,32 位,约 5 Mb 的文件,代码的核心部分是:

while 1:
    c = f.read(1)
    if not c: break

2.6: io.open 20.4s, open 5.1s
2.7: io.open  3.3s, open 4.8s # io.open is better
3.1: io.open  3.6s, open 3.6s # effectively same code is used

所以更好的建议是:一般来说,除非你有很好的理由,比如想让 2.7 运行得更快,否则不要随便使用 io.open。

撰写回答