通过子进程或其他方法的 Python 速度命令行调用
Posted
技术标签:
【中文标题】通过子进程或其他方法的 Python 速度命令行调用【英文标题】:Python Speed Command Line Call via Subprocess or Another Method 【发布时间】:2013-10-06 18:50:54 【问题描述】:在 Python 中有没有比使用subprocess.call
方法更高效或更快的方法?我注意到一年前有一个关于此的 SO 问题 (Python subprocess module much slower than commands (deprecated)),但由于 Python 删除了该替代方案而贬值,所以我想看看这是否是现在唯一且最快的方法来调用命令来自 Python 的 shell。具体来说,我正在运行以下命令:
subprocess.call("foo",shell=True)
或者我应该使用os
?
谢谢。
【问题讨论】:
你能发布原始问题的链接吗? 谢谢我已经添加了引用的链接。 该帖子声称 subprocess 有 2ms 的适度劣势,并且还建议跳过中间 shellsubprocess.call(["foo"])
会产生更大的差异。如果您确实需要从代码中提取 2ms,请考虑使用 C 扩展。
好的,感谢您的澄清。
@tdelaney 增加了 2(实际上是 2.76)毫秒,是的,当您的基线为 3 毫秒时,这意味着使用子流程的时间增加了 92%。也许我们对“谦虚”有不同的定义,但这没什么好打喷嚏的
【参考方案1】:
可能不会。您可能可以稍微加快调用速度,但根据我的经验,最大的收获是只启动一次子进程,然后让它保持活动状态。
创建新进程是一项非常昂贵的操作,Python 无法真正降低成本。
因此,与其调用/bin/ls path...
100 次,不如创建一个从标准输入读取路径并返回所需输出而不退出的外部进程。
作为一个(悲伤的)例子:在 ca。 1997 年,我编写了一个包装器,使 Java 1 编译器的速度提高了 1000 倍,该包装器使 VM 保持活动状态,并在通过套接字接收选项后启动编译。这主要不是因为进程创建时间,还因为在那时和之前启动 Java VM 需要很长时间。
【讨论】:
"创建一个从标准输入读取路径并返回所需输出而不退出的外部进程。"你能举个例子来说明如何做到这一点吗? @Mooncrater 您将需要外部进程的源代码。修改它以从标准输入而不是 CLI 参数中获取参数。在父级中使用subprocess.Popen()
来启动和控制它。【参考方案2】:
尝试使用 subprocess.Popen() 代替。它有许多优点。详情请参考
Difference between subprocess.Popen and os.system
http://docs.python.org/2/library/subprocess.html
【讨论】:
以上是关于通过子进程或其他方法的 Python 速度命令行调用的主要内容,如果未能解决你的问题,请参考以下文章
Python 子进程 - 通过 SSH 运行多个 shell 命令