【问题标题】:stdin seems much slower than stdout (python). Why?标准输入似乎比标准输出(python)慢得多。为什么?
【发布时间】:2011-03-22 07:22:06
【问题描述】:

我有两个需要相互通信的 python 程序(一个是子进程)。目前我正在通过stdinstdout 这样做。但是,写入子进程的 stdin 似乎非常缓慢。

a.py,一个接受任意行输入并打印时间的程序:

from time import time, sleep
from sys import stdout, stdin
while True:
    stdin.readline()
    stdout.write('%f\n' % time())
    stdout.flush()

b.py,一个运行a.py 的程序,以及写入程序的stdin 并从它的stdout 读取所需的时间:

from time import time
from subprocess import PIPE, Popen
from threading import Thread
stdin_times = []
stdout_times = []
p = Popen(['python', 'a.py'], stdin=PIPE, stdout=PIPE)
for i in range(100000):
    t1 = time()
    p.stdin.write(b'\n')
    p.stdin.flush()
    t2 = float(p.stdout.readline().strip().decode())
    t3 = time()
    stdin_times.append(t2 - t1)
    stdout_times.append(t3 - t2)
p.kill()
print('stdin (min/ave):', min(stdin_times), sum(stdin_times) / len(stdin_times))
print('stdout (min/ave):', min(stdout_times), sum(stdout_times) / len(stdout_times))

样本输出:

stdin (min/ave): 1.69277191162e-05 0.000138891274929
stdout (min/ave): 1.78813934326e-05 2.09228754044e-05

我在 Ubuntu 10.10 上使用 Python 3.1.2。

为什么写入a.pystdin 比读取它的stdout 慢得多? 无论如何我可以让这两个程序更快地通信吗?

【问题讨论】:

  • 您运行此测试多少次才能得出这些数字?也许在计划a.pyb.py 之间,crond 可能已经启动了一个updatedb 任务,或者ntpdate 可能扭曲了你的时钟或者......
  • 更新为显示平均值
  • 在这种情况下,您不需要平均值,您需要最少时间(因为“最佳情况”=“没有其他干扰”)。
  • 您还希望从计时循环中清除所有无关的垃圾。缓存方法查找,使用 b'\n' 代替调用 encode,计算 t2 记录 t3。但是,您仍然会受到操作系统调度程序的支配。如果它决定工作进程是非交互式的,它可能会针对 IO 吞吐量而不是低延迟优化其调度。
  • 我已经更新以显示分钟并且它们具有可比性,但我认为这对我没有帮助。我不是要证明标准输入在理论上的劣势;我只需要我的流程能够更快地进行通信(平均而言)。

标签: python io stdio


【解决方案1】:

我想看看您是否可以在禁用输入和输出缓冲时重现此问题。我有一种预感,默认情况下输出正在(行)缓冲(就像在大多数语言中一样:perl、.NET、C++ iostreams)

【讨论】:

  • python 子进程默认 bufsize 为 0 docs.python.org/release/3.1.3/library/subprocess.html>。另外,每次需要刷新输出时,我显然都在刷新。当我需要将缓冲区大小设置为 0 时,是否刷新?
  • 一样好,但不一样。根据所花费的时间,它可能会有所不同......
【解决方案2】:

如果我尝试几次,数字的差异非常大。

也许您应该设置一个更健全的测试来对标准输入和标准输出进行基准测试,而不会产生很多其他开销,因此您不会测量 CPU 上正在发生的其他事情。此外,您正在测量字符串操作和浮点转换。

【讨论】:

  • 这不是相反的。在您的示例中,stdin 仍然较慢。另外,我更新了我的帖子以显示平均值
  • 这实际上并没有颠倒过来,只是两者都以相同的输出格式打印——stdin 时间仍然大于stdout 时间。
猜你喜欢
  • 2012-03-11
  • 2013-11-06
  • 2018-09-20
  • 1970-01-01
  • 1970-01-01
  • 2013-09-18
  • 2019-11-22
相关资源
最近更新 更多