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