从脚本语言中调用shell命令会降低性能吗?

pep*_*per 7 php ruby python shell perl

在编写python,perl,ruby或php时,我会经常使用...

PERL:
`[SHELL COMMAND HERE]`
system("[SHELL]", "[COMMAND]", "[HERE]")

Python
import os
os.system("[SHELL COMMAND HERE]")
from subprocess import call
call("[SHELL]", "[COMMAND]", "[HERE]")

ruby 
`[SHELL COMMAND HERE]`
system("[SHELL COMMAND HERE]")

PHP
shell_exec ( "SHELL COMMAND HERE" )
Run Code Online (Sandbox Code Playgroud)

在shell中生成子进程多少会降低程序的性能?例如,我只是用perl和libcurl编写一个脚本,并且使用所有libcurl的参数很难让它工作.我停止使用libcurl并且刚开始使用curl并且性能似乎改进了,脚本变得更加容易,而且,我可以在只有基本perl(没有cpan模块)和安装基本shell实用程序的系统上运行我的脚本.

为什么产生这个子shell被认为是糟糕的编程习惯?从理论上讲,它应该比在语言中使用特定的绑定/等效库慢得多吗?

fer*_*rix 6

执行shell命令的第一个原因是可维护性.没有语言切换,任务之间的上下文切换就足够糟糕 安全性也是一个考虑因素,但编码实践将使其不那么重要(避免注射......)

有几个因素会影响绩效:

  1. 分叉进程:这需要一段时间,但是如果正在执行的代码运行良好,则这变得不太重要.
  2. 优化变得不可能:当控件移交给另一个进程时,解释器或编译器无法执行任何优化.此外,您无法执行任何优化.
  3. 阻止:Shell命令是阻塞操作.它们不会像代码的本机部分那样被安排.
  4. 解析:如果需要对输出做一些事情,则需要对其进行解析.在本机代码中,数据已经存在于相关的数据结构中.解析也容易出错.
  5. 命令行生成:为可执行文件生成命令行可能需要迭代.有时,这比在本地执行相同操作需要更多周期.

当外部命令在循环中执行时,会出现大多数这些问题.可能很容易找到这些都不成问题的例子.


Bre*_*aub 5

谁说生成 shell 进程是不好的做法?当心教条主义者。没有硬性规定来定义何时做或不做。在您的示例中,当您开始使用curl时,您可以更快地完成项目并且获得更好的性能。证据总是在布丁中

就性能而言,分叉(并执行)一个新进程会引起影响,因此您应该避免在较短的操作中使用它。但是,如果子进程运行几秒钟,您将不会注意到启动它所需的 25 毫秒(只是一个占位符 #)。但是,如果有一个运行速度非常快且经常调用的瞬态函数,则通过子 shell 调用它会导致性能显着下降。

关于子流程的一件事是它们可以从命令行独立测试。所以它们确实是独立的工具,这对于某些问题非常有用。

最后要考虑的一件事。如果您相信“适合工作的正确工具”,并且正确的工具恰好已经在盒子里,并且您可以通过花钱来解决手头的任务,那么为什么不呢?我一生中见过很多代码,但这些代码最终都是无关紧要的,因为问题已经通过一些免费提供的(并且已经安装的)工具解决了。它只是碰巧不适合程序员选择的整体(即单一工具)实现环境。

推论是“如果你只有一把锤子,那么一切看起来都像钉子”。不要害怕伸手去拿螺丝刀,并提防“一锤子统治一切”的邪教分子。