PHP exec() performance

2022-08-30 18:22:17

以下 PHP 代码确实会返回大约 3.5 秒的运行时间(多次测量并取平均值):

$starttime = microtime(true);
exec('/usr/local/bin/convert 1.pdf -density 200 -quality 85% 1.jpg');
$endtime = microtime(true);
$time_taken = $endtime-$starttime;

当我在ssh终端上运行相同的命令时,运行时减少到大约0.6秒(使用命令行工具测量)。time

imagemagick 库的版本是

Version: ImageMagick 6.7.0-10 2012-12-18 Q16 http://www.imagemagick.org
Copyright: Copyright (C) 1999-2011 ImageMagick Studio LLC
Features: OpenMP

造成这种时差的原因可能是什么?

在stackoverflow上,一个类似问题的答案是,开销来自Web服务器必须启动线程/shell。这真的是原因吗?我认为线程是轻量级的,并且不需要很长时间来启动/终止。

在调用之前,我将 imagemagick 使用的线程数(因为这是 OpenMP 中的一个错误?,参考)设置为 1,使用 .PHP的运行时不会有太大变化,无论我为设置什么值。无论如何,在这个版本中,OpenMP中似乎没有错误,因为命令行执行的运行时是可以的。execexec('env MAGICK_THREAD_LIMIT=1');MAGICK_THREAD_LIMIT

任何关于如何改进上述命令的运行时的建议将不胜感激。

非常感谢您的帮助。


答案 1

当您登录到 Unix 计算机时,无论是通过键盘还是通过 ssh,您都会创建一个新的 shell 实例。外壳通常类似于 或 。shell 允许您执行命令。/bin/sh/bin/bash

使用 时,它还会创建一个 shell 的新实例。该实例执行您发送给它的命令,然后退出。exec()

创建 shell 命令的新实例时,它有自己的环境变量。因此,如果您这样做:

exec('env MAGICK_THREAD_LIMIT=1');
exec('/usr/local/bin/convert 1.pdf -density 200 -quality 85% 1.jpg');

然后创建两个 shell,第一个 shell 中的设置永远不会到达第二个 shell。要将环境变量放入第二个 shell 中,您需要类似如下的内容:

exec('env MAGICK_THREAD_LIMIT=1; /usr/local/bin/convert 1.pdf -density 200 -quality 85% 1.jpg');

现在,如果您认为 shell 本身可能是问题所在,因为制作 shell 需要很长时间,请使用您知道的东西对其进行测试,几乎不需要时间:

$starttime = microtime(true);
exec('echo hi');
$endtime = microtime(true);
$time_taken = $endtime-$starttime;

在这一点上,你知道尝试找到一些方法来使shell实例化得更快。

希望这有帮助!


答案 2

我已经为计算机编程超过56年了,但这是我第一次遇到这样的错误。因此,我花了将近一周的时间试图了解从via执行程序与直接在命令行执行程序时执行速度差7倍。作为这项工作的一部分,我还仔细研究了在网络上提出这个问题的所有时间。以下是我的发现:perlphpexecperl

(1)这是一个在2002年首次报告的错误,在随后的11年内没有修复。

(2)该错误与 交互的方式有关,因此这两个组织都将责任推给另一个组织。apachephp

(3)该错误在,系统或任何替代方案上是相同的。exec

(4) bug 不依赖于 exec-ed 程序是 、 还是其他什么。perlexe

(5)UNIX和Windows上的错误是相同的。

(6)该错误与图像无关或与图像无关。我在完全不同的设置中遇到了错误。imagemagick

(7)这个错误与分叉,shell,bash等的启动时间无关。

(8)该错误无法通过更改服务的所有者来修复。apache

(9)我不确定,但我认为这与调用子例程的开销大大增加有关。

当我遇到这个问题时,我有一个程序可以在40秒内执行,但通过需要304秒。我的最终解决方案是弄清楚如何优化我的程序,以便它可以在0.5秒内直接执行,或者在3.5秒内执行。所以我从来没有解决问题。perlexecexec


推荐