В PHP более эффективно использовать лямбда-выражение для вызываемого, чем строка (или массив)?

В PHP некоторые функции принимают в качестве аргумента «вызываемый», что означает, что вы можете указать функцию, которая будет выполняться в какой-то момент вниз по линии. Одним из примеров является array_map.

PHP позволяет указать вызываемый несколькими способами, например:

// 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
);

Теперь я полагаю, что последняя форма оценивается механизмом PHP один раз во время компиляции, в то время как другая форма может оцениваться во время выполнения, возможно, для каждого вызова, что означает, что использование замыкания было бы гораздо более эффективным для большого количества вызовов. Это предположение верно?

6

Решение

Я выполнил функцию несколькими различными способами и записал время выполнения.
Похоже, что использование строковой ссылки на обычную функцию намного эффективнее.

Резюме

  1. Нормальное определение функции с помощью array_map ():
                   4,001193714
  2. Лямбда-определение вне цикла с помощью array_map ():
         10.1116962
  3. Нормальное определение функции и вызов:
                                  3,208938837
  4. Лямбда-определение и вызов внутри цикла:
                          10.32323852
  5. Лямбда-определение вне цикла:
                                       9,616424465
  6. Нормальное определение функции и call_user_func ():
            13.72040915
  7. Лямбда-определение вне цикла и call_user_func (): 19.98814855

Нормальное определение функции и вызов

$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";
  1. +3,1148610115051
  2. +3,0175619125366
  3. +3,5064949989319
  4. +3,3637712001801
  5. +3,0420050621033

Средний: 3.208938837

Лямбда-определение и вызов внутри цикла

$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";
  1. 9,857855797
  2. 10.07680297
  3. 10.35639596
  4. 10.51450491
  5. 10.81063294

Среднее: 10.32323852

Лямбда-определение вне цикла

$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";
  1. 9,098902941
  2. 9,580584049
  3. 9,370799065
  4. 9.90805316
  5. 10.12378311

Средний балл: 9,616424465

Нормальное определение функции и 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";
  1. 12.80056691
  2. 13.47905684
  3. 14.51880193
  4. 13.79459596
  5. 14.00902414

Среднее: 13.72040915

Лямбда-определение и внешний цикл и 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";
  1. 18.99004483
  2. 20.08601403
  3. 20.52800584
  4. 20.16949892
  5. 20.16717911

Средний: 19,98814855

Нормальное определение функции с помощью 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";
  1. 3,727953911
  2. 4,213405848
  3. 4,068621874
  4. 4,180392027
  5. 3,815594912

Среднее: 4.001193714

Лямбда-определение вне цикла с помощью 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";
  1. 9,418456793
  2. 10.07496095
  3. 10.1241622
  4. 10.74794412
  5. 10.19295692

Средний балл: 10,1116962

3

Другие решения

Других решений пока нет …