Python 子进程 check_output 比调用慢得多

标签 python performance subprocess

我试图理解为什么会这样。我正在调用命令以在 Ubuntu 服务器 12.04 上重新启动网络。

快速执行

当我使用以下三种方式之一调用命令时,执行大约需要 0.1 秒:

  1. 直接在终端
  2. 使用 os.system 的 python 脚本
  3. 使用 subprocess.call 的 python 脚本

终端 session :

root@ubuntu:~# time /etc/init.d/networking restart
 * Running /etc/init.d/networking restart
 * Reconfiguring network interfaces...
real    0m0.105s

root@ubuntu:~# time python -c "import os;
> os.system('/etc/init.d/networking restart')"
 * Running /etc/init.d/networking restart
 * Reconfiguring network interfaces...
real    0m0.111s

root@ubuntu:~# time python -c "import subprocess;
> subprocess.call(['/etc/init.d/networking', 'restart'])"
 * Running /etc/init.d/networking restart
 * Reconfiguring network interfaces...
real    0m0.111s

执行缓慢

但是,如果我使用 subprocess.check_output 或 Popen 并尝试读取输出,则需要 23 秒。慢多了似乎只有当我尝试使用将返回命令输出的函数时才会发生这种显着差异。我想了解为什么会发生这种情况,并找到一个解决方案来执行此命令并在不花费很长时间的情况下获取它的输出。

终端 session :

root@ubuntu:~# time python -c "import subprocess;
> print subprocess.check_output(['/etc/init.d/networking', 'restart'])"
 * Running /etc/init.d/networking restart
 * Reconfiguring network interfaces...
real    0m23.201s

root@ubuntu:~# time python -c "from subprocess import Popen, PIPE;
> print Popen(['/etc/init.d/networking', 'restart'], stdout=PIPE).stdout.read()"
 * Running /etc/init.d/networking restart
 * Reconfiguring network interfaces...
real    0m23.201s

更新

其中一条评论建议尝试使用 tee 命令。结果非常有趣。在没有任何 python 参与的终端中,如果使用 tee,则需要相同的 23 秒。我仍然很好奇为什么,但至少这可能会提供更多关于正在发生的事情的线索。

root@ubuntu:~# time /etc/init.d/networking restart | tee out.txt
 * Running /etc/init.d/networking restart
 * Reconfiguring network interfaces...
real    0m23.181s

最佳答案

以下代码基于 J.F. Sebastian 发表的精彩评论。下面的代码按预期在 0.1 秒内运行,并将命令的输出返回到字符串。

from subprocess import check_call, STDOUT
from tempfile import NamedTemporaryFile

with NamedTemporaryFile() as f:
    check_call(['/etc/init.d/networking', 'restart'], stdout=f, stderr=STDOUT)
    f.seek(0)
    output = f.read()

关于Python 子进程 check_output 比调用慢得多,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13835055/

相关文章:

python - 是否可以在独立的 C 中实现 Python yield 功能?

Python - 哈希二进制值

java - AEM 性能问题(缓慢的内存泄漏)org.slf4j.helpers.BasicMarker 和 org.slf4j.helpers.BasicMarkerFactory

mysql - 如何像这样调整mysql中的自连接表?

python - 使用Python从音频文件中提取F0,抖动和微光

python - 未找到定义变量

javascript - 在 JS 中计算直方图的相似值的最佳方法是什么?

python - subprocess.Popen() 启动两个进程而不是一个

python - 如何通过 mailx 和子进程发送邮件?

Windows 上的 Python 子进程问题