0% found this document useful (0 votes)
59 views

Simec

This document presents benchmarks comparing the performance of PHP code versus C code for computationally intensive tasks like calculating the Fibonacci sequence and multiplying large matrices. The C code was significantly faster than the PHP code for both tasks, with the C Fibonacci calculation taking about 1/80th of the time. Developing PHP modules in C and calling them from PHP can improve performance for applications requiring complex mathematical operations or where speed is critical. Profiling tools like Xdebug, Qcachegrind and Webgrind are discussed for identifying bottlenecks in applications. Sample code is provided to calculate the Fibonacci sequence and multiply 800x800 matrices in both C and PHP.

Uploaded by

Shala Edin
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
59 views

Simec

This document presents benchmarks comparing the performance of PHP code versus C code for computationally intensive tasks like calculating the Fibonacci sequence and multiplying large matrices. The C code was significantly faster than the PHP code for both tasks, with the C Fibonacci calculation taking about 1/80th of the time. Developing PHP modules in C and calling them from PHP can improve performance for applications requiring complex mathematical operations or where speed is critical. Profiling tools like Xdebug, Qcachegrind and Webgrind are discussed for identifying bottlenecks in applications. Sample code is provided to calculate the Fibonacci sequence and multiply 800x800 matrices in both C and PHP.

Uploaded by

Shala Edin
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 6

Alen Šimec, Davor Lozić, Lidija Tepeš Golubić: BENCHMARKING PHP MODULES

Informatol. 50, 2017., 1-2, 95-100 95


INFO- 2173 UDK: 004.43C:004.43PHP-047.44
Primljeno/Received: 2017-03-08 Professional Paper/Stručni rad

BENCHMARKING PHP MODULES

MJERENJE BRZINE RADA PHP MODULA

Alen Šimec, Davor Lozić, Lidija Tepeš Golubić


Zagreb University of Applied Sciences, Zagreb, Croatia
Tehničko veleučilište u Zagrebu, Zagreb, Hrvatska

Abstract Sažetak
This paper presents how C programming language Ovaj rad predstavlja kako se za ovakve probleme
could be used for this type of tasks, created as PHP može koristiti programski jezik C, kao PHP modul,
module and then get imported in the PHP language. te pozvati iz PHP jezika. Cilj ovog ujedno je pokazati
The purpose of this paper is to show how and when kako i kada je bolje, umjesto običnih PHP funkcija,
is better to build PHP modules in C, instead of nor- raditi PHP module u programskom jeziku C te pri-
mal PHP functions, and to show negative sides of kazati i negativne strane takvoga programiranja. Rad
this type of programming. Profiling, as an important objašnjava i pronalazak „uskog-grla” u aplikacijama
aspect of finding application bottlenecks, is also dis- pomoću sustava kao što su Xdebug, qcachegrind i
cussed. Profiling systems like Xdebug, Qcachegrind webgrind. U radu je prikazan izvorni kod koji raču-
and Webgrind are also elucidated. This paper con- na Fibonaccijev niz te množi matrice veličine 800x800
tains source code which calculates Fibonacci se- u programskim jezicima C i PHP. Dobiveni rezultati
quence and multiplies 800x800 matrices written in C pokazuju da je u svim slučajevima gdje je bio po-
and PHP programming languages. Results show that treban matematički izračun, programski jezik C bio
whenever there is a need for a mathematical compu- višestruko brži te da je u takvim slučajevima isplativ-
tation, C will be many times faster and that it is ije napisati izvorni kod u programskom jeziku C i
much more cost-effective to write such code in C and izraditi PHP modul.
create a PHP module.

1 Introduction 2 PHP modules

PHP language is mostly designed for develop- PHP modules must be inside php-src/ext fold-
ing web applications /1/ and, as such, is not suita- er and after executing ext_skel script, the skeleton
ble for complex mathematical operations, nor is for your model should be created. After the skele-
suitable for systems where speed of such operation ton is created, phpize prepares the build so it
executions is important. PHP is mostly used for needs to be executed:
generating dynamic HTML content /2/. Since PHP php-src/ext/mymod# phpize
is built with C, it is possible to create PHP modules Artificial intelligence is focused on presenta-
in C and import them in the PHP language /3/. tion of knowledge and its use. It is critical for
Examples given in this paper are executed and knowledge management. Artificial intelligence is
tested on Linux operating system, specifically not only focused on explicit knowledge that can be
Debian distribution, but it should work on any relatively easy to formalise with some form of its
system with few or not any changes at all. presentation (manufacturing rules, semantic net-
Qcachegrind and Webgrind are tested with OSX. works, triplet object of attribute value, frame-
PHP source code could be downloaded with ver- works, predicates of the first row). Relationships
sioning control system like Git: between business intelligence and other technolo-
git clone https://github.com/php/php-src.git gies that are directly related to business intelli-

ISSN 1330-0067 Coden: IORME7


Alen Šimec, Davor Lozić, Lidija Tepeš Golubić: BENCHMARKING PHP MODULES
96 Informatol. 50, 2017., 1-2, 95-100

gence can be observed through five characteristics: // declaring PHP function which will call
inputs, nature of inputs, outputs, components, and my_fib()
users /4/. PHP_FUNCTION(confirm_mymod_compiled)
Iside mymod.c are some templates for func- {
tions which a developer can remove or leave for long f;
testing purposes. In this example, the module is if
called mymod so the test function is called con- (zend_parse_parameters(ZEND_NUM_ARGS()
firm_mymod_compiled and this is the function TSRMLS_CC, "l", &f) == FAILURE) {
where the testing is performed. This is a simple return;
function which returns a simple number 100 to the }
user.
long r = my_fib(f);
// confirm_mymod_compiled() function
PHP_FUNCTION(confirm_mymod_compiled){ RETVAL_LONG(r);
RETVAL_LONG(100); }
} Testing is quite simple with microtime before
and after the code. PHP function reference shows
// inside shell (compiling and installing) microtime returns the current UNIX timestamp in
./configure && make && sudo make install microseconds:

// module needs to be included inside php.ini $startTime = microtime(true);


extension=mymod.so
// your code
// restarting server (in this example, Apache2)
sudo /etc/init.d/apache2 restart $endTime = microtime(true);
$result = $endTime - $startTime;
// calling a function from PHP
<?php After executing the script few times, test shows
echo confirm_mymod_compiled(); // 100 (in average) that the C version is about 80 times
faster when calculating 34th Fibonacci number:
2.1 Simple PHP benchmarking

Here is a simple test using Fibonacci Series in


PHP and in C, both using recursion.
Speed (seconds)
PHP version:
function fibonacci($f){ C
if($f < 2){ PHP
0 2 4 6
return 1;
}else{ Speed (seconds)
return fibonacci($f-1) + fibonac- C 0,064888954
ci($f-2); PHP 5,378473997
}
Figure 1 - Benchmarking C and PHP with Fibo-
}
nacci Series calculated with recursion (lower is
C version:
better)
long my_fib(long f){
if (f < 2){
return 1; 2.2. Matrix multiplication
}else{ Multiplication of two matrices can be very
return(my_fib(f - 1) + my_fib(f - 2)); computationally expensive (O3) /5/. There are also
} ways to reduce some steps and speed up the com-
} putation but they are not part of this paper.
In C language, matrix could be imple-
mented as a 2-dimensional array.

ISSN 1330-0067 Coden: IORME7


Alen Šimec, Davor Lozić, Lidija Tepeš Golubić: BENCHMARKING PHP MODULES
Informatol. 50, 2017., 1-2, 95-100 97

PHP_FUNCTION(run_multiplication) }
{
int n = 800; for ($i = 0; $i < $n; $i++) {
for ($j = 0; $j < $n; $j++) {
// matrices $secondM[$i][$j] = rand() % 100 + 1;
int firstM[n][n], secondM[n][n], re- }
sultM[n][n]; }

// counters and a temporary sum Multiplication in PHP stays the same:


int i, j, k;
int sum = 0; for ($i = 0; $i < $n; $i++) {
for ($j = 0; $j < $n; $j++) {
srand(time(NULL)); $sum = 0;
for (i = 0; i < n; i++) { for ($k = 0; $k < $n; $k++) {
for (j = 0; j < n; j++) { $sum = $sum + $firstM[$i][$k] * $se-
firstM[i][j] = rand() % 100 + condM[$k][$j];
1; }
} $resultM[$i][$j] = $sum;
} }
}
for (i = 0; i < n; i++) {
for (j = 0; j < n; j++) { 2.3. Explanation
secondM[i][j] = rand() %
100 + 1; Relatively speaking, PHP is not a slow lan-
} guage. The problem is that PHP is an interpreted
} language. While executing C which is already
… compiled and directly executed on a processor,
} PHP language needs to go through some phases
like parsing, converting to opcodes, etc. and this is
Two 800x800 matrices are populated with ran- the heart of the problem.
dom numbers between 1 and 100. srand function The problem also worth mentioning here is the
sets the global seed variable which changes the stack. Whenever a function is called, a new stack is
output of the rand function /6/. Multiplication in created only for that function and that is what is
this example takes O3: happening inside the Fibonacci version with recur-
sion. The advantage that compiled languages have
for (i = 0; i < n; i++) { here, is the possibility of having a great compiler
for (j = 0; j < n; j++) { which can inline the function (like copying the
sum = 0; code) instead of calling the function and creating
for (k = 0; k < n; k++) { the new stack. Without recursion, results (approx-
sum = sum + firstM[i][k] * secondM[k][j]; imately, C was 110 times better) are better:
}
resultM[i][j] = sum;
}
}

Defining matrices in PHP is similar:

$n = 800;
$firstM = $secondM = $resultM = [];
for ($i = 0; $i < $n; $i++) {
for ($j = 0; $j < $n; $j++) {
$firstM[$i][$j] = rand() % 100 + 1;
}

ISSN 1330-0067 Coden: IORME7


Alen Šimec, Davor Lozić, Lidija Tepeš Golubić: BENCHMARKING PHP MODULES
98 Informatol. 50, 2017., 1-2, 95-100

The first line enables the profiler. The second


line formats the filename where the profiler data
Speed (seconds)
will be saved and the third line tells the profiler
C what is the default directory for saving the result.
PHP One can also add a “trigger” which will only ena-
0 0,001 0,002
ble/save Xdebug results if there is a parameter in
Speed (seconds) the request:
C 1,50204E-05
PHP 0,001790047 xdebug.profiler_enable_trigger = 1
# only enabled if XDEBUG_PROFILE is passed
Figure 2 - Benchmarking C and PHP with Fibo-
nacci Series calculated without recursion - 1000th
As stated on the Xdebug profiler homepage,
Fibonacci number (lower is better)
Xdebug outputs a profiling information in the
Example with multiplying matrices has few form of a cachegrind file. To sum it up, there are
things which needs to be pointed out. In the exam- options for all major operating systems:
ple written in C programming language, matrices
are inside a stack (no malloc-family function were Operating system Software
called) and the PHP example creates matrices on Microsoft Windows QCacheGrind or Win-
CacheGrind
the heap which is slower /7/. Before calling the
Linux KCacheGrind
PHP example, a script must allow PHP to use 1GB
MacOS QCacheGrind
of memory:
Figure 4 - "cachegrind" software for different
operating systems
ini_set('memory_limit', '1024M');
It’s recommended to install Graphviz also so a
user could see a call graph. For example, to install
QCacheGrind on OSX, one could do it with home-
brew. First, Qt should be installed:
brew install qt

Speed (seconds)
After installing qt, qcachegrind could be in-
stalled:
C
brew install qcachegrind --with-graphviz
PHP
0 100 200 300

Speed (seconds) Graphviz installs dot, plain text graph descrip-


C 2,46 tion language. Graphviz installs dot in
PHP 254,03 /usr/local/bin/dot but in order to qcachegrind find
dot, it should be in /usr/bin/dot. One can create a
Figure 3 - matrix multiplication symlink for dot /8/ like this:
In this example, C is approximately 103 times sudo ln -s /usr/local/bin/dot /usr/bin/dot

faster.
After installing qcachegrind, running it is easy:
3 Benchmarking with Xdebug, $ qcachegrind
Qcachegrind and Webgrind
After opening and importing generated debug
First step when optimizing PHP applica-
file, qcachegrind shows a list of functions called in
tions is profiling. With Xdebug, one can determine
the request. Generated debug file is in the
bottlenecks in the application. To enable Xdebug
profiler, several lines must be added to the php.ini xdebug.profiler_output_dir directory specified in
php.ini.
file:

xdebug.profiler_enable = 1
xdebug.profiler_output_name = xdebug.out.%t
xdebug.profiler_output_dir = /tmp

ISSN 1330-0067 Coden: IORME7


Alen Šimec, Davor Lozić, Lidija Tepeš Golubić: BENCHMARKING PHP MODULES
Informatol. 50, 2017., 1-2, 95-100 99

cd webgrind-master

Serve the application with PHP: php –S lo-


calhost:1234

After opening localhost:1234 and opening your


debug files, webgrind should show something
similar like in Figure 8.

Figure 5 - list of function calls in one request


Figure 5 shows a list of function calls in a single
PHP request.

Figure 8- webgrind list of function calls

4 Conclusion

If a developer needs to create a cutting-edge


Figure 6 - call graph code which needs to be fast and efficient, doing
module in C and importing it into PHP is the best
There is also a call graph, generated with
way to go. Module in C is much faster but the
Graphviz. Figure 6 shows a generated call graph
downside is that you need to know something
which shows how and where PHP functions are
about PHP internals. If there is a need for creating
called. There is also a callee map, shown in Figure
a module which needs to use heap memory, some
7.
part of PHP, maybe module needs to be called
while PHP is starting or shutting down, developer
needs to understand PHP internals and structures
like zvalue /9/, understand a lot of macros, deal
with memory management and with a lot of low
programming concepts.
To find bottlenecks, developers can use
Xdebug with Qcachegrind or Webgrind. It’s crucial
to find a good development time – execution speed
ratio. There is no need to write everything as a
Figure 7 - callee map module in C but writing only parts which are bot-
There is a qchachegrind alternative, called tlenecks could give some amazing improvements.
Webgrind. Webgrind is a web frontend which
understands Xdebug profiling information. To
install Webgrind, it must be downloaded: References
wget
/1/ Padilla, A.; Hawkins, T.: Turning PHP Web projects
https://github.com/jokkedk/webgrind/archive/mas
for Maximum Performance. Springer Science, New
ter.zip
York, 2010.
ISBN 978-1-4302-2899-8
Unzip the application: unzip master.zip

ISSN 1330-0067 Coden: IORME7


Alen Šimec, Davor Lozić, Lidija Tepeš Golubić: BENCHMARKING PHP MODULES
100 Informatol. 50, 2017., 1-2, 95-100

/2/ Smijulj, A.; Meštrović, A.: Izgradnja MVC modular- /7/ Gribble, P.: Memory: Stack vs Heap (Summer 2012),
nog radnog okvira. 2016.
Zbornik Veleučilišta u Rijeci, Vol. 2 (2014), No. 1, s. http://gribblelab.org/CBootcamp/7_Memory_Stack_v
215-232. ISSN 1848-1299 s_Heap.html
/3/ Bijakšić S.; Markić, B.; Bevanda, A.: Business intelli- /8/ Kehrer, P.: How to install qcachegrind (kcachegrind)
gence and analysis of selling in retail. Informatolo- on Mac OSX Snow Leopard, 2011.
gia, Vol.47 No.4. 2014. ISSN: 1330-0067 https://langui.sh/2011/06/16/how-to-install-
/4/ Ibid. qcachegrind-kcachegrind-on-mac-osx-snow-leopard/
/5/ Stothers A.J.: On the Complexity of Matrix Multipli- /9/ Popov, N.: Understanding PHP's internal function
cation. 2010, University of Edinburgh. definitions. 2012.
http://www.maths.ed.ac.uk/sites/default/files/atoms/ http://nikic.github.io/2012/03/16/Understanding-
files/stothers.pdf PHPs-internal-function-definitions.html
/6/ Parlante, N.: Essential C, 1996-2003, Stan-
ford.http://cslibrary.stanford.edu/101/EssentialC.pdf

ISSN 1330-0067 Coden: IORME7

You might also like