022 Оптимизации
Поскольку код в Zephir иногда очень высокоуровневый, компилятор C, возможно, не сможет в достаточной мере оптимизировать этот код .
Zephir, благодаря своему компилятору AOT (ahead-of-time), способен оптимизировать код во время компиляции, потенциально увеличивая скорость его выполнения или уменьшая объем памяти, необходимый программе.
Вы можете включить оптимизацию, передав имя с префиксом -f:
zephir -fstatic-type-inference -flocal-context-pass
Оптимизация может быть отключена путем передачи имени с префиксом -fno-:
zephir -fno-static-type-inference -fno-call-gatherer-pass
В последних версиях zephir-parser оптимизация может быть настроена в конфигурационном файле config.json.
{ "namespace": "mae", "name": "My Awesome Extension", "author": "ACME", "version": "1.0.0", "optimizations": { "static-type-inference": true, "static-type-inference-second-pass": true, "local-context-pass": true, "constant-folding": true, "static-constant-class-folding": true, "call-gatherer-pass": true, "check-invalid-reads": false, "private-internal-methods": false, "public-internal-methods": false, "public-internal-functions": true } }
Поддерживаются следующие режимы оптимизации:
call-gatherer-pass
Этот проход подсчитывает, сколько раз функция или метод вызывается в одном методе. Это позволяет компилятору вводить встроенные кэши, чтобы избежать поиска методов или функций:
class MyClass extends OtherClass { public function getValue() { this->someMethod(); this->someMethod(); // This method is called faster } }
check-invalid-reads
Этот флаг заставляет типы проверки обнаруживать недопустимые чтения в процессе компиляции,
constant-folding
Сворачивание констант-это процесс упрощения константных выражений во время компиляции. При включении этой оптимизации упрощается следующий код:
public function getValue() { return (86400 * 30) / 12; }
Преобразуется в:
public function getValue() { return 216000; }
internal-call-transformation
----
local-context-pass
Этот этап компиляции перемещает в стек переменные, которые будут выделены в куче. Эта оптимизация может уменьшить количество обращений памяти которые программа должна сделать.
static-constant-class-folding
Эта оптимизация заменяет значения констант класса во время компиляции:
class MyClass { const SOME_CONSTANT = 100; public function getValue() { return self::SOME_CONSTANT; } }
Преобразуется в:
class MyClass { const SOME_CONSTANT = 100; public function getValue() { return 100; } }
static-type-inference
Этот прогон компиляции очень важен, поскольку он ищет динамические переменные, которые потенциально могут быть преобразованы в статические / примитивные типы, которые лучше оптимизируются базовым компилятором.
Следующий код использует набор динамических переменных для выполнения математических вычислений:
public function someCalculations(var a, var b) { var i = 0, t = 1; while i < 100 { if i % 3 == 0 { continue; } let t += (a - i), i++; } return i + b; }
Переменные a, b и i используются исключительно в математических операциях и поэтому могут быть преобразованы в статические переменные, используя другие пропуски компиляции. После этого прохода компилятор автоматически перезаписывает этот код:
public function someCalculations(int a, int b) { int i = 0, t = 1; while i < 100 { if i % 3 == 0 { continue; } let t += (a - i), i++; } return i + b; }
Отключив этот проход компиляции, все переменные будут поддерживать тип, с которым они были изначально объявлены, без оптимизации.
static-type-inference-second-pass
Это позволяет использовать второй этап вывода типа, что улучшает работу, выполняемую на основе данных, собранных первым этапом вывода статического типа.