Я принял решение использовать блокировки для своих обратных вызовов вместо create_function
и как таковые поддерживать только PHP> 5.3 в основном из-за повышенной отладки, а также потому, что я предположил (что это говорит о допущении?), Что накладные расходы on- компиляция « create_function
в моей ситуации могла бы компенсировать любые дополнительные сравнения и такие, которые должны были быть сделаны внутри функции.
Это может все еще иметь место (для моего приложения), и требуется дополнительное тестирование, но меня заинтересовал вывод этого (очень) простого теста, который показывает, что метод create_function
более чем в два раза быстрее, чем закрытие, когда оно может удалить только четыре условных выражения (и concats). Очевидно, что в моем тестовом случае нет дополнительной обработки, и именно там большая часть скорости будет получена или потеряна, но в случае, когда у вас мало дополнительной обработки, но есть много условных выражений (которые можно удалить) и callback называется достаточно раза, я начал думать, что лучше использовать create_function
.
Однако с очевидным сходством между create_function
и eval
я create_function
этого.
Итак, главный вопрос: каковы различия между анонимными функциями, созданными с помощью create_function
и функциями закрытия?
Несколько конкретных вопросов, о которых я думаю, будут create_function
даже если функция eval
отключена? И я уверен, что где-то недавно я где-то читал, что функции create_function
будут загрязнять глобальное (или класс) пространство имен, даже если объявлены как внутренние функции, но закрытие не будет. Я не могу найти ссылку на это сейчас, но являются ли эти или оба эти утверждения истинными?
Это небольшое испытание, которое я выполнил:
<?php function foo($a=true, $b=true, $c=true, $d=true) { $inner1 = create_function( '', '$r = \''.($a ? 'a' : ''). ($b ? 'b' : ''). ($c ? 'c' : ''). ($d ? 'd' : '').'\'; return $r;' ); $inner2 = function() use ($a, $b, $c, $d) { $r = ''; if($a) { $r .= 'a'; } if($b) { $r .= 'b'; } if($c) { $r .= 'c'; } if($d) { $r .= 'd'; }; return $r; }; $time = microtime(true); for ($x=0; $x<99999; ++$x) { $i1out = $inner1(); } echo '1:'.(microtime(true)-$time).'<br>'; $time = microtime(true); for ($x=0; $x<99999; ++$x) { $i2out = $inner2(); } echo '2:'.(microtime(true)-$time).'<br>'; echo var_dump($i1out===$i2out).'<br>'; } foo();
Функция construct function() {..}
является анонимной функцией, и эта функция часто реализуется вместе с замыканиями . Ни create_function
ни анонимные функции не загрязняют глобальное пространство имен.
Поскольку анонимные функции могут обращаться к окружающим переменным (закрывающей части), они теоретически могут быть немного медленнее. С другой стороны, если вы используете кеширование байт-кода (а если нет, то вас явно не интересует производительность), я ожидаю, что «компиляция» накладных расходов анонимных функций будет немного медленнее.
Однако крайне маловероятно, что разница между анонимными функциями и create_function
является источником проблем с производительностью. Поэтому я бы выбрал более читаемую форму анонимной функции, если вам так повезло иметь целевую платформу с php> 5.3.
create_function
создает глобальную функцию, которая сохраняется для остальной части программы. create_function
просто возвращает имя функции (строку), и поэтому не имеет понятия, если у вас все еще есть доступ к этому имени, где-то где-то или нет. Следовательно, это не может быть «сбор мусора», даже если у вас нет доступа к имени больше.
Это означает, что большая проблема в том, что если вы создаете множество функций с помощью create_function
, это приведет к тому, что ваша программа закончится без памяти:
for ($i = 0; $i < 1000000; $i++) { $f = create_function('', ''); // do stuff // don't use $f anywhere after this point }
тогда как с анонимными функциями этого не произойдет (закрытие будет собирать мусор).