Прежде всего — кажется, что есть много вопросов об основах функциональности тиков, поэтому я хочу добавить верхний комментарий пользователя на php.net/declare в кучу для тех, кто ищет дополнительную информацию. Я нашел это, пока копался, пытаясь выяснить следующее.
Итак, я работаю над написанием простого помощника по отладке. Я хочу добавить функции трассировки и бенчмаркинга — в основном, для чего идеально подходит функциональность тиков.
Дело в том, что я хочу включить и отключить бенчмаркинг в зависимости от произвольных условий, возникающих во время обработки скрипта. Я на самом деле не ищу исправленную отладку а-ля scoped declare() { ... }
,
Что я хочу сделать, это поставить declare();
вверху моего скрипта, а затем зарегистрируйте и отмените регистрацию моей функции отладки / тестирования (галочка) в зависимости от ситуации. Un / регистрация не будет происходить (слишком) часто, поэтому она эффективна и разумна.
Но потом мне стало любопытно: когда у меня нет зарегистрированной функции галочки … делает ли тот факт, что я запустил declare(ticks=1);
влияет на эффективность исполнения? В любом случае это приводит к тому, что какая-либо дополнительная обработка становится постоянно включенной?
Анализ исходного кода PHP (7) показывает, что ответ технически да, но я еще не уверен как.
Ответ, кажется, в zend_compile.c: 8200Похоже, что эта функция откладывает обработку компиляции до соответствующих подпрограмм, затем, если галочки включены, она дополнительно генерирует ZEND_TICKS
код операции в opline через zend_emit_tick()
в : 2167. страница кода опкода для TICKS кажется согласуется с этим выводом; он показывает пример разобранного списка опкодов, в котором разбросаны опкоды TICKS, и мне было интересно, как они туда попали, пока я не обнаружил вышеизложенное.
ZEND_TICKS
обработчик (в zend_vm_def.h: 6859кажется звонит zend_ticks_function()
, Это сопоставлено с ticks_function()
в zend.c: 754, который в свою очередь сопоставлен с php_run_ticks()
в main.2013. это окончательно определено в php_ticks.c, где это все:
void php_run_ticks(int count)
{
zend_llist_apply_with_argument(
&PG(tick_functions),
(llist_apply_with_arg_func_t) php_tick_iterator,
&count
);
}
Да. Неплохо.
Но вот в чем дело. Если я declare(ticks=1);
вышеприведенная отправка выполняется буквально для каждого выполненного оператора. Это… Уч. Для долгосрочных сценариев, содержащих большое число итераций, жесткие циклы обработки, Мне интересно, как сильно это сложится.
Проблема в том, что я даже не уверен, как это проверить. Единственный способ, которым я мог предусмотреть это, — это синтезировать некоторый байт-код PHP, а затем найти способ внедрить это непосредственно в интерпретатор байт-кода PHP.
И это приводит к моему вопросу: насколько большое влияние на производительность оказывает эта дополнительная диспетчеризация на практике? Как я могу определить это?
Очевидно, что вышеупомянутое исследование было выполнено на каноническом интерпретаторе PHP.net. Я еще не изучал, как HHVM делает это вообще (пока), но я бы даже не подумал узнать, как он справляется с этим.
Задача ещё не решена.
Других решений пока нет …