从PHP调用外部库。什么更快:exec还是扩展? 我需要从C++到外部的图书馆进行调用,并显示结果。平台是Linux、Apache、PHP

从PHP调用外部库。什么更快:exec还是扩展? 我需要从C++到外部的图书馆进行调用,并显示结果。平台是Linux、Apache、PHP,php,web-applications,php-extension,Php,Web Applications,Php Extension,我目前的想法是使用PHP服务,它将调用我的库/程序。我发现有两种方法可以做到这一点: 1) 使用PHP“exec”函数 2) 编写PHP扩展 我很好奇什么更有效?更快?减少服务器的负载 我可能需要每秒打4个电话,所以我希望尽可能做到最好 如果您知道从网页中调用C++库或程序的其他(更有效的)方法,请告诉我。 非常感谢, Robusta执行官显然比调用编译后的PHP扩展慢。Ext_skel是你的密友 编辑: 关于exec比内置扩展慢,没有任何理论依据。运行一个strace并检查PHP脚本中一个ex

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

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

我可能需要每秒打4个电话,所以我希望尽可能做到最好

如果您知道从网页中调用C++库或程序的其他(更有效的)方法,请告诉我。 非常感谢,

Robusta执行官显然比调用编译后的PHP扩展慢。Ext_skel是你的密友

编辑: 关于exec比内置扩展慢,没有任何理论依据。运行一个strace并检查PHP脚本中一个exec和一个已编译扩展调用的syscalls数量如何

以下是一些基准:

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

**执行4次:

time./a.php(EXEC)

实际0.944s
用户0m0.700s
系统0m0.244s

time./b.php(php扩展)

实际0.268s
用户0m0.212s
系统0m0.056s

**执行1000次:

time./a.php(EXEC)

真正的3m47.042s
用户2m48.239s
sys 0m56.784s

time./b.php(php扩展)

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

我认为这不需要任何解释。编译后的扩展运行更快,更环保,占用更少的cpu时间。被认为更好。此外,通过扩展,您可以重用资源。如果要从同一个图像创建10个不同的版本,该怎么办?然后您不必重新创建对象
newimagick('filename')每次

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

实际0m3.712s
用户0m3.552s
sys 0m0.156s

脚本A内容:

#!/usr/bin/php5
<?php

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

?>
#!/usr/bin/php5
<?php

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

?>
#!/usr/bin/php5
<?php

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

?>
#/usr/bin/php5
脚本B内容:

#!/usr/bin/php5
<?php

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

?>
#!/usr/bin/php5
<?php

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

?>
#!/usr/bin/php5
<?php

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

?>
#/usr/bin/php5
脚本bx内容:

#!/usr/bin/php5
<?php

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

?>
#!/usr/bin/php5
<?php

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

?>
#!/usr/bin/php5
<?php

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

?>
#/usr/bin/php5
使用forks编写STACKTRACE脚本(简单运行):

脚本b STACKTRACE和forks(简单运行):

执行者显然比调用已编译的PHP扩展慢得多。Ext_skel是你的密友

编辑: 关于exec比内置扩展慢,没有任何理论依据。运行一个strace并检查PHP脚本中一个exec和一个已编译扩展调用的syscalls数量如何

以下是一些基准:

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

**执行4次:

time./a.php(EXEC)

实际0.944s
用户0m0.700s
sys 0m0.244s

time./b.php(php扩展)

实际0.268s
用户0m0.212s
系统0m0.056s

**执行1000次:

time./a.php(EXEC)

真正的3m47.042s
用户2m48.239s
sys 0m56.784s

time./b.php(php扩展)

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

我认为这不需要任何解释。编译后的扩展运行更快,更环保,占用更少的cpu时间。被认为更好。此外,通过扩展,您可以重用资源。如果要从同一个图像创建10个不同的版本,该怎么办?然后您不必重新创建对象
newimagick('filename')每次

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

实际0m3.712s
用户0m3.552s
sys 0m0.156s

脚本A内容:

#!/usr/bin/php5
<?php

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

?>
#!/usr/bin/php5
<?php

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

?>
#!/usr/bin/php5
<?php

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

?>
#/usr/bin/php5
脚本B内容:

#!/usr/bin/php5
<?php

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

?>
#!/usr/bin/php5
<?php

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

?>
#!/usr/bin/php5
<?php

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

?>
#/usr/bin/php5
脚本bx内容:

#!/usr/bin/php5
<?php

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

?>
#!/usr/bin/php5
<?php

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

?>
#!/usr/bin/php5
<?php

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

?>
#/usr/bin/php5
使用forks编写STACKTRACE脚本(简单运行):

脚本b STACKTRACE和forks(简单运行):

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

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


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

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

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


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

如果您想省去编写PHP扩展的麻烦(exec太慢)您可能希望为正在使用的库编写某种Web服务(例如,使用XML-RPC或SOAP/REST),并从php代码中调用它


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

如果您想省去编写php扩展的麻烦(exec太慢)您可能希望为正在使用的库编写某种Web服务(例如,使用XML-RPC或SOAP/REST),并从php代码中调用它

这应该更容易些