I need to make calls from webpage to external library written in C++ and display the result. Platform is Linux, Apache, PHP.
My current idea is to use PHP service which will call my library/program. I found that there are two possible ways to do this: 1) use PHP 'exec' function 2) write PHP extension
I am curious what works more effective? Faster? Less load the server?
I will probably need to do 4 calls per second, so I want to be as optimal as possible.
P.S. If you are aware of some other (more effective) way of c开发者_StackOverflow社区alling C++ library or program from webpage, please let me know.
Thanks a lot,
RobustaAn extension is theoretically faster because it avoids the overhead of creating a new process. It's also a "cleaner" solution (no awkward program arguments escaping; you are able to parse arbitrary PHP values such as objects instead of only strings, etc.).
However, if you already have a command line program that uses that library, it will be easier for you to just execute it instead of writing an extension.
Note that if you only make 4 calls per second, performance-wise it's indifferent which method you use, unless your library requires expensive initialization that can be avoided by having persistent (cross-request) state stored in a PHP extension.
Execs are definetly slower than calling a compiled PHP extension. Ext_skel is your close friend.
EDIT: There is nothing theoretical about exec is slower than a built in extension. What about running an strace and check how many syscalls an exec inside a PHP script and a call to a compiled extension does.
Here are some benchmarks:
System: VMWARE Workstation, C2DUO E8400, 2GB RAM
**Executed 4 times:
time ./a.php (EXEC)
real 0m0.944s
user 0m0.700s
sys 0m0.244s
time ./b.php (PHP EXTENSION)
real 0m0.268s
user 0m0.212s
sys 0m0.056s
**Executed 1000 times:
time ./a.php (EXEC)
real 3m47.042s
user 2m48.239s
sys 0m56.784s
time ./b.php (PHP EXTENSION)
real 3m36.631s
user 2m46.922s
sys 0m49.627s
I don't think this needs any explanation. Compiled extension runs faster, more eco friendly, eats less cpu time. Considered better. Also, with extensions you can reuse resources. What if you want to create 10 different versions from the same image? Then you don't have to recreate the object new imagick('filename');
every time.
time ./bx.php (PHP EXTENSION REUSING RESOURCE)
real 0m3.712s
user 0m3.552s
sys 0m0.156s
Script A contents:
#!/usr/bin/php5
<?php
for ($i=0; $i < 1000; $i++)
{
exec('/usr/bin/convert -thumbnail 150 src1.jpg dst.jpg');
}
?>
Script B contents:
#!/usr/bin/php5
<?php
for ($i=0; $i < 1000; $i++)
{
$img = new imagick('src1.jpg');
$img->thumbnailImage( 150, null );
$img->writeImage('dst.jpg');
} //for
?>
Script bx contents:
#!/usr/bin/php5
<?php
$img = new imagick('src1.jpg');
for ($i=0; $i < 1000; $i++)
{
$img->thumbnailImage( 150, null );
$img->writeImage('dst.jpg');
} //for
?>
Script a STACKTRACE with forks (simple run): LINK
Script b STACKTRACE with forks (simple run): LINK
If you want to spare yourself the hassle of writting a php extension (exec is too slow) you might want to write some kind of webservice of the library you are using (e.g. with XML-RPC or SOAP/REST) and call this from your php code.
This should be easier to debug (Simply log the requests you made and replay them) as well as easier to separate (need to run one part on a different host for various reasons? :P)
As for as I am concerning WebService is much slower than exe program. But is having the advantage of platform independent as ZeisS said.
And I strongly agree with Emil Vikstrom . Consider an example, in your house(system) you(OS) will give more preference for family members(exe) than guests(webservice). In case of recursive functions, exe will run much faster than webservices.
Speed vs. Portability. If you link another library against PHP, you have to keep it updated; hence need a build system or better yet a custom package for your distribution. This is practically not a big deal. But it's still simpler to just use a commandline utility when available.
So, if it is a library that can be used in a session-like fashion (multiple calls, adapt environment) you should definitely build a wrapper. If you don't invoke it >10 times per second, the speed difference is negligible. Go for the execve() method then. It's the Unix way and factually more robust if your application has a certain lifetime expectation.
精彩评论