1

我需要从网页调用用 C++ 编写的外部库并显示结果。平台是Linux、Apache、PHP。

我目前的想法是使用 PHP 服务来调用我的库/程序。我发现有两种可能的方法来做到这一点:1)使用 PHP 'exec' 函数 2)编写 PHP 扩展

我很好奇什么更有效?快点?减轻服务器负载?

我可能需要每秒进行 4 次调用,所以我希望尽可能地达到最佳状态。

PS 如果您知道从网页调用 C++ 库或程序的其他(更有效)方式,请告诉我。

非常感谢,
罗布斯塔

4

5 回答 5

8

扩展理论上更快,因为它避免了创建新进程的开销。它也是一个“更干净”的解决方案(没有尴尬的程序参数转义;您可以解析任意 PHP 值,例如对象而不是字符串等)。

但是,如果您已经有一个使用该库的命令行程序,那么您只需执行它而不是编写扩展程序会更容易。

请注意,如果您每秒只进行 4 次调用,那么在性能方面,您使用哪种方法无关紧要,除非您的库需要昂贵的初始化,而这可以通过将持久(交叉请求)状态存储在 PHP 扩展中来避免。

于 2010-06-13T12:30:11.600 回答
4

执行程序肯定比调用已编译的 PHP 扩展慢。Ext_skel 是你的好朋友。

编辑:没有任何关于 exec 比内置扩展慢的理论。运行 strace 并检查 PHP 脚本中的 exec 有多少系统调用以及对已编译扩展的调用如何呢?

以下是一些基准:

系统:VMWARE 工作站,C2DUO E8400,2GB RAM

**执行 4 次:

时间./a.php(执行)

真实 0m0.944s
用户 0m0.700s
系统 0m0.244s

时间 ./b.php (PHP 扩展)

真实 0m0.268s
用户 0m0.212s
系统 0m0.056s

**执行 1000 次:

时间./a.php(执行)

真实 3m47.042s
用户 2m48.239s
系统 0m56.784s

时间 ./b.php (PHP 扩展)

真实 3m36.631s
用户 2m46.922s
系统 0m49.627s

我认为这不需要任何解释。编译后的扩展运行速度更快,更环保,占用更少的 CPU 时间。考虑更好。此外,通过扩展,您可以重用资源。如果你想从同一个图像创建 10 个不同的版本怎么办?这样您就不必new imagick('filename');每次都重新创建对象。

time ./bx.php (PHP 扩展重用资源)

真实 0m3.712s
用户 0m3.552s
系统 0m0.156s

脚本A内容:

#!/usr/bin/php5
<?php

for ($i=0; $i < 1000; $i++)
{
    exec('/usr/bin/convert -thumbnail 150 src1.jpg dst.jpg');
}

?>

脚本 B 内容:

#!/usr/bin/php5
<?php

for ($i=0; $i < 1000; $i++)
{
    $img = new imagick('src1.jpg');
    $img->thumbnailImage( 150, null );
    $img->writeImage('dst.jpg');
} //for

?>

脚本 bx 内容:

#!/usr/bin/php5
<?php

$img = new imagick('src1.jpg');
for ($i=0; $i < 1000; $i++)
{
    $img->thumbnailImage( 150, null );
    $img->writeImage('dst.jpg');
} //for

?>

使用分叉编写 STACKTRACE 脚本(简单运行): LINK

带有分叉的脚本 b STACKTRACE(简单运行): LINK

于 2010-06-13T12:28:48.090 回答
1

如果您想省去编写 php 扩展的麻烦(exec 太慢),您可能需要编写您正在使用的库的某种 web 服务(例如使用 XML-RPC 或 SOAP/REST)并从您的php代码。

这应该更容易调试(只需记录您发出的请求并重播它们)以及更容易分离(出于各种原因需要在不同的主机上运行一个部分?:P)

于 2010-06-13T12:48:26.390 回答
0

至于我所关心的 WebService 比 exe 程序慢得多。但正如蔡司所说,具有平台独立的优势。

我非常同意Emil Vikstrom的观点。考虑一个例子,在你的房子(系统)中,你(操作系统)会比客人(网络服务)更偏爱家庭成员(exe)。在递归函数的情况下,exe 将比 webservices 运行得快得多。

于 2010-06-13T13:43:58.620 回答
0

速度与便携性。如果你将另一个库链接到 PHP,你必须保持更新;因此需要一个构建系统或更好的自定义包来进行分发。这实际上没什么大不了的。但是在可用时使用命令行实用程序仍然更简单。

因此,如果它是一个可以以类似会话的方式(多次调用,适应环境)使用的库,那么您绝对应该构建一个包装器。如果您不调用它 > 每秒 10 次,则速度差异可以忽略不计。然后使用 execve() 方法。如果您的应用程序有一定的生命周期预期,这是 Unix 方式,实际上更健壮。

于 2010-06-13T15:01:11.307 回答