Python 3中最快的标准输入输出方法?

24 投票
3 回答
33288 浏览
提问于 2025-04-17 05:29

我在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 个回答

1

可能不行。

最后,print 会调用 sys.stdout.write()。不过因为 print 是一个内置函数,可能是用 C 语言实现的,所以它的速度可能比直接调用 sys.stdout.write() 还要快。

所有的输入输出都必须通过 sys.stdout 返回的对象,这就是瓶颈。sys.stdin 也是一样。

没有什么魔法可以让这个变得更快。

如果你需要更快的输入输出,可以试试这些方法:

  • 改为写入文件
  • 使用缓冲输入输出(在一个小的 shell 脚本中用 buffer 命令来处理标准输出)。
  • 使用内存映射文件
  • 确保读取你输出的进程能跟上。例如,DOS 控制台就挺慢的。如果你把输出通过一个慢的命令传递,这可能会阻塞你的 Python 进程。

[编辑] 看起来 SPOJ.pl 是一个程序员竞赛网站。在这种情况下,输入输出速度不是问题所在:你用了一个不好的算法来解决这个问题。

一个好的算法和一个普通算法之间的速度差异可以轻松达到 10 到 100,000 倍。我曾经通过改几行代码,让原本需要 45 分钟的代码在 5 秒内运行。

2

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解决方案会比其他语言写的简单粗暴的解决方案要快。

15

下面的方法可能是最快的:

  1. 一次性读取所有输入,使用 os.read(0, some_big_enough_number)

  2. 处理输出,把结果收集到一个列表 results 中。

  3. 一次性写出所有输出,使用 os.write(1, "".join(results))

我记得有一次我发现 os.read()os.write() 有时候比用 Python 的输入输出更快,但我不记得具体的细节了。

撰写回答