Python 3中最快的标准输入输出方法?
我在SPOJ.pl上用Python 3.1.2解决了一些问题,发现有些人对简单问题的解决速度很快,这让我想知道有没有更快的方法来处理输入和输出。
我试过使用
input()
print()
还有
sys.stdin.readline()
sys.stdout.write()
或者说
for line in sys.stdin:
#Handle input
sys.stdout.write(output)
来处理每一行的内容。
我还尝试把所有的输出都收集到列表里,然后在处理完所有内容后一次性打印出来。
但是这些方法的执行时间都差不多。
有没有更快的方法来处理标准输入和输出呢?
3 个回答
可能不行。
最后,print
会调用 sys.stdout.write()
。不过因为 print
是一个内置函数,可能是用 C 语言实现的,所以它的速度可能比直接调用 sys.stdout.write()
还要快。
所有的输入输出都必须通过 sys.stdout
返回的对象,这就是瓶颈。sys.stdin
也是一样。
没有什么魔法可以让这个变得更快。
如果你需要更快的输入输出,可以试试这些方法:
- 改为写入文件
- 使用缓冲输入输出(在一个小的 shell 脚本中用
buffer
命令来处理标准输出)。 - 使用内存映射文件
- 确保读取你输出的进程能跟上。例如,DOS 控制台就挺慢的。如果你把输出通过一个慢的命令传递,这可能会阻塞你的 Python 进程。
[编辑] 看起来 SPOJ.pl 是一个程序员竞赛网站。在这种情况下,输入输出速度不是问题所在:你用了一个不好的算法来解决这个问题。
一个好的算法和一个普通算法之间的速度差异可以轻松达到 10 到 100,000 倍。我曾经通过改几行代码,让原本需要 45 分钟的代码在 5 秒内运行。
SPOJ让你可以选择多种编程语言。你是否在比较自己代码的执行时间和其他语言写的解决方案呢?
为了好玩,我提交了以下几种解决方案来比较运行时间,都是针对第一个问题(代号TEST
)。
C++解决方案 (G++ 4.3.2)
#include <iostream>
int main ( int, char** )
{
for ( int number=0; (std::cin >> number) && (number != 42); ) {
std::cout << number << std::endl;
}
}
查看这个提交。
Python (2.5)解决方案
import sys
for line in sys.stdin:
number = int(line)
if number == 42:
break
print number
查看这个提交。
结论
我不敢保证这两种语言的性能是最好的,但代码量不多,优化的空间也有限。
我测得C++的运行时间是0.00
,而Python的运行时间是0.04
。假设提交给这两个程序的数字序列是一样的,我觉得跟其他语言的解决方案比较运行时间几乎没有意义(见下一段)。
不过,这种情况只适用于简单问题。大多数复杂问题需要选择合适的算法,选错了算法后果会很严重。在这种情况下,精心设计的Python解决方案可能仍然比精心设计的C++解决方案慢,但一个好的Python解决方案会比其他语言写的简单粗暴的解决方案要快。
下面的方法可能是最快的:
一次性读取所有输入,使用
os.read(0, some_big_enough_number)
。处理输出,把结果收集到一个列表
results
中。一次性写出所有输出,使用
os.write(1, "".join(results))
。
我记得有一次我发现 os.read()
和 os.write()
有时候比用 Python 的输入输出更快,但我不记得具体的细节了。