In PHP, some function take a "callable" as an argument, meaning you can specify a function to be executed at some point down the line. One example is array_map
.
PHP allows you to specify a callable in multiple ways, for example:
// as a string:
$lowerCaseStrings = array_map('strtolower', $arrayOfStrings);
// object methods as an array
// (this could be done with DateTime directly, of course):
class DateFactory {
private $format;
public function __construct($format) {
$this->format = $format;
}
public function newDate($dateString) {
return DateTime::createFromFormat($this->format, $dateString);
}
}
$factory = new DateFactory('Y-m-d');
$dates = array_map(array($factory, 'newDate'), $arrayOfDateStrings);
// as a lambda expression / closure:
$dates = array_map(
function ($dateString) {
return DateTime::createFromFormat('Y-m-d', $dateString);
},
$arrayOfDateStrings
);
Now, I figure that the latter form gets evaluated by the PHP engine once during compilation, while the other might be evaluated during runtime, probably for each call, meaning using a closure would be far more efficient for a large number of calls. Is that assumption correct?
I executed a function several different ways and recorded the run times. It looks like using a string reference to a regular function is much more efficient.
Summary
Normal function definition and call
$start_time = microtime(true);
function run_this() {
// Empty function
}
for($i = 0; $i < 5000000; $i++) {
run_this();
}
print "Execution time: " . (microtime(true) - $start_time) . "\n";
Average: 3.208938837
Lambda definition and call within loop
$start_time = microtime(true);
for($i = 0; $i < 5000000; $i++) {
$run_this = function () {
// Empty function
};
$run_this();
}
print "Execution time: " . (microtime(true) - $start_time) . "\n";
Average: 10.32323852
Lambda definition outside loop
$start_time = microtime(true);
$run_this = function () {
// Empty function
};
for($i = 0; $i < 5000000; $i++) {
$run_this();
}
print "Execution time: " . (microtime(true) - $start_time) . "\n";
Average: 9.616424465
Normal function definition and call_user_func()
$start_time = microtime(true);
function run_this () {
// Empty function
};
for($i = 0; $i < 5000000; $i++) {
call_user_func('run_this');
}
print "Execution time: " . (microtime(true) - $start_time) . "\n";
Average: 13.72040915
Lambda definition and outside loop and call_user_func()
$start_time = microtime(true);
$run_this = function () {
// Empty function
};
for($i = 0; $i < 5000000; $i++) {
call_user_func($run_this);
}
print "Execution time: " . (microtime(true) - $start_time) . "\n";
Average: 19.98814855
Normal function definition with array_map()
$arr = array_pad([], 5000, 0);
$start_time = microtime(true);
function run_this () {
// Empty function
};
for($i = 0; $i < 1000; $i++) {
array_map('run_this', $arr);
}
print "Execution time: " . (microtime(true) - $start_time) . "\n";
Average: 4.001193714
Lambda definition outside loop with array_map()
$arr = array_pad([], 5000, 0);
$start_time = microtime(true);
$run_this = function () {
// Empty function
};
for($i = 0; $i < 1000; $i++) {
array_map($run_this, $arr);
}
print "Execution time: " . (microtime(true) - $start_time) . "\n";
Average: 10.1116962
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With