Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

PHP exec() performance

Tags:

The following PHP code does return me a runtime of about 3.5 seconds (measured multiple times and averaged):

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

When i run the same command over a ssh terminal, the runtime is reduced to about 0.6 seconds (measured with the command line tool time).

The version of the imagemagick library is

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

What could be the reason for this time difference?

One answer to a similar question here on stackoverflow was that the overhead comes from the Webserver having to start a thread/shell. Could this be really the reason? I thought threads are leightweight and don't take long at all to start/terminate.

Prior to calling exec i set the number of threads used by imagemagick (because this was/is a bug in OpenMP?, Reference) to 1 with exec('env MAGICK_THREAD_LIMIT=1');. The runtime from PHP does not change much, no matter what value i set for MAGICK_THREAD_LIMIT. Anyway there does not seem to be a bug in OpenMP on in this version because the runtime of the command line execution is ok.

Any suggestions of how i could improve the runtime of the above command would be greatly appreciated.

Thank you very much for your help.

like image 744
Philipp Avatar asked Jan 11 '13 12:01

Philipp


Video Answer


1 Answers

When you log in to a Unix machine, either at the keyboard, or over ssh, you create a new instance of a shell. The shell is usually something like /bin/sh or /bin/bash. The shell allows you to execute commands.

When you use exec(), it also creates a new instance of a shell. That instance executes the commands you sent to it, and then exits.

When you create a new instance of a shell command, it has it's own environment variables. So if you do this:

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

Then you create two shells, and the setting in the first shell never gets to the second shell. To get the environment variable into in the second shell, you need something like this:

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

Now, if you think that the shell itself may be the problem, because it takes too long to make a shell, test it with something that you know takes almost no time:

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

At that point you know to try and find some way to make the shell instantiate faster.

Hope this helps!

like image 103
Gustav Bertram Avatar answered Sep 30 '22 18:09

Gustav Bertram