从PHP调用外部库。什么更快:exec还是扩展? 我需要从C++到外部的图书馆进行调用,并显示结果。平台是Linux、Apache、PHP
我目前的想法是使用PHP服务,它将调用我的库/程序。我发现有两种方法可以做到这一点: 1) 使用PHP“exec”函数 2) 编写PHP扩展 我很好奇什么更有效?更快?减少服务器的负载 我可能需要每秒打4个电话,所以我希望尽可能做到最好 如果您知道从网页中调用C++库或程序的其他(更有效的)方法,请告诉我。 非常感谢,从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
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代码中调用它
这应该更容易些