Python 2.x和3.x中的BufferedReader
我有一个程序可以在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 个回答
使用2.7版本应该能解决这个问题。可以查看一下PEP 3116和Python 2.7的文档。
在2.6版本中,io模块的一部分是用Python写的,而在2.7及以上版本中,整个模块都是用C语言写的。
要给你一个更完整的答案,我们需要看看你的代码(或者更好的是,给我们一个可以运行的代码简版)。
不过,从你的输出信息中,我们可以得到一些部分答案: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。