Results 1 to 3 of 3
Threaded View
-
08-09-2006, 05:56 PM #1Newbie
- Join Date
- Aug 2006
- Posts
- 10
PHP: Function Calls vs Object Method Calls vs Class Method Calls
Today I was looking at different ways to speed up some php scripts. Eventually I decided to go back and double check to see which was actually the fastest on the computer and php versions I was using.
I did the tests on a function, a static method, and two object methods, one with a parameter and one without, the results should show why. In each function, I went through an array and peformed a few functions on each. The array was randomly generated with another script. It has 129 elements. Each element has a key 32 bytes long and a value 4KB long. Finally, just to be fair, each test was run 5 times, only taking the fastest result.
I expected the function to outpeform the objects and classes, the static method to be in second, and for the second object to shine above the first one.
Here's the script I used to benchmark. You can use it to test for yourself or let me know of any errors in it, I know for a fact that I copied and pasted a bit too much at first (no, they shouldn't all take the exact number of ms).
PHP Code:<?php
// this is a very large array.
// about 129 elements with 32 byte keys and 4KB value
include('array.php');
function double($array) {
$return = array();
foreach($array as $k => $v) {
$return['l' . strtolower($k)] = strtolower($k);
$return['u' . strtoupper($k)] = strtoupper($k);
}
return $return;
}
class loop {
static function double($array) {
$return = array();
foreach($array as $k => $v) {
$return['l' . strtolower($k)] = strtolower($k);
$return['u' . strtoupper($k)] = strtoupper($k);
}
return $return;
}
}
class loopy {
function double($array) {
$return = array();
foreach($array as $k => $v) {
$return['l' . strtolower($k)] = strtolower($k);
$return['u' . strtoupper($k)] = strtoupper($k);
}
return $return;
}
}
class loopy2 {
function __construct($array) {
$this->array = $array;
}
function double() {
$return = array();
foreach($this->array as $k => $v) {
$return['l' . strtolower($k)] = strtolower($k);
$return['u' . strtoupper($k)] = strtoupper($k);
}
return $return;
}
}
// run tests 5 times
$time = array(
'function' => time(),
'class' => time(),
'object' => time(),
'object2' => time(),
);
$count = 0;
$loop = new loopy;
$loop2 = new loopy2($test_array);
do {
$start = microtime(true);
double($test_array);
$end = microtime(true);
$ms = $end - $start;
$time['function'] = $ms < $time['function'] ? $ms : $time['function'];
$start = microtime(true);
$loop->double($test_array);
$end = microtime(true);
$ms = $end - $start;
$time['object'] = $ms < $time['object'] ? $ms : $time['object'];
$start = microtime(true);
$loop2->double();
$end = microtime(true);
$ms = $end - $start;
$time['object2'] = $ms < $time['object2'] ? $ms : $time['object2'];
$start = microtime(true);
loop::double($test_array);
$end = microtime(true);
$ms = $end - $start;
$time['class'] = $ms < $time['class'] ? $ms : $time['class'];
} while($count++ < 30);
echo 'The Function took: ' . number_format($time['function'] * 1000, 4) . 'ms<br>
The Class took: ' . number_format($time['class'] * 1000, 4) . 'ms<br>
The First Object took: ' . number_format($time['object'] * 1000, 4) . 'ms<br>
The Second Object took: ' . number_format($time['object2'] * 1000, 4) . 'ms';
?>
With PHP 5.1.4, on console with no Accelerator, I tested 3 times because a few of the results varied.
The Function took: 1.8969ms
The Class took: 1.9600ms
The First Object took: 1.8070ms
The Second Object took: 1.6961msThe Function took: 1.9751ms
The Class took: 1.7090ms
The First Object took: 1.7331ms
The Second Object took: 1.7149msThe Function took: 1.6789ms
The Class took: 1.5011ms
The First Object took: 2.0032ms
The Second Object took: 1.6921ms
Going by this, which one should you use? Does't appear to matter much anymore. They all go the same speeds. But being the person that I am, I decided to see how it would peform with an Accelerator.
I used eAccelerator v0.9.5-beta2 and ran the test 6 times and here are the final three results (the first three times for the accelerator/server to cache script):
The Function took: 1.5180ms
The Class took: 1.9290ms
The First Object took: 1.8249ms
The Second Object took: 1.4539msThe Function took: 1.7889ms
The Class took: 1.5960ms
The First Object took: 1.8580ms
The Second Object took: 1.5540msThe Function took: 1.7719ms
The Class took: 1.8320ms
The First Object took: 1.7920ms
The Second Object took: 1.5960ms
So now you know its possible to use OOP to go faster than you would with normal function calls. But if you think I stopped these tests here you were wrong.
Since PHP 5.2 RC1 is out, I decided to also test with that, especially since I've heard there have been many optimizations made in PHP 5.2. Here are the results from the console test (no accelerator):
The Function took: 1.7679ms
The Class took: 1.4899ms
The First Object took: 1.7741ms
The Second Object took: 1.6789msThe Function took: 1.7662ms<br>
The Class took: 1.8530ms<br>
The First Object took: 1.8070ms
The Second Object took: 1.4200msThe Function took: 1.7700ms<br>
The Class took: 1.6489ms<br>
The First Object took: 1.7800ms
The Second Object took: 1.6079ms
Results with PHP 5.2.0RC1 and eAccelerator v0.9.6-dev (SVN Revision 263).
The Function took: 1.7970ms
The Class took: 1.7869ms
The First Object took: 1.7481ms
The Second Object took: 1.6541msThe Function took: 1.8730ms
The Class took: 1.6170ms
The First Object took: 1.8201ms
The Second Object took: 1.7350msThe Function took: 1.6630ms
The Class took: 1.9059ms
The First Object took: 1.7660ms
The Second Object took: 1.3831ms
Conclusion: Programming Correctly, OOP can outpeform normal function calling every time.
Some things to consider:
I did not include the creation of the objects in the time tested. Including it will most likely affect results, but there is a reason I didn't include it (explained below).
Now, the differences between using each of these techniques may be insignificant in many cases. 0.0004 seconds isn't much time to save and most people won't notice it or even care that you just saved .003 execution time in your scripts by switching to a more OOP approach. These benchmarks are probably more useful for recursive functions that have 500+ calls in your script. While .003 seconds time isn't much to save 1.5 might be a bit more to try to save.