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
Это позволяет использовать второй этап вывода типа, что улучшает работу, выполняемую на основе данных, собранных первым этапом вывода статического типа.
