Difference between revisions of "Compile"

From SunFlurry wiki
Jump to: navigation, search
 
m (1 revision imported)
(No difference)

Revision as of 08:43, 7 February 2021

  Compile (Системные функции)
Объект:Функции общего назначения
Статус разработки: Реализована
Тип:Функция
Обращение к БД:Нет
Исключения:Невозможно превратить в строку, число, ошибка в выражении
Визуальность:Нет

Функция производит компиляцию блока текста, заданного на внутреннем языке, и возвращает объект, представляющий результат компиляции. В зависимости от второго аргумента, блок может компилироваться в контексте текущей функции, глобальных модулей или без доступа к внешним переменным и функциям. Функция вызывает прерывание, если компиляция прервана из-за ошибки. Результирующий объект можно использовать многократно с функциями Exec и ExecEx, это быстрее, чем компилировать блок текста при каждом вызове. Несмотря на называние, в блок является набором произвольных инструкций и функций, а не одной функцией, иными словами, блок текста может быть произвольным модулем.

Синтаксис

Compile(<Блок для компилирования (STRING)>,<Степень изолированности (INT)>=0):<Компилированная функция в виде объекта (COMPILEDFUNCTION)>

Аргументы

  • <Блок для компилирования (STRING)> - Произвольный блок инструкций, может содержать имена функций, переменных, операции, магические функции, особые конструкции, в т.ч. объявления новых функций.
  • <Степень изолированности (INT)> - (необязательный аргумент) Аргумент задает среду компиляции, и может принимать следующие значения:
    • 0 (по умолчанию) -- производить компиляцию в контексте текущей функции (в которой вызвана функция Compile). Это дает возможность использовать все переменные и все локальные функции текущий функции, а также глобальные переменные и функции.
    • 1 -- производить компиляцию в глобальных функций. Это дает возможность использовать в блоке текста только глобальные переменные и функции. Такой вариант изолированности предпочтительнее, если функция в дальнейшем будет экспортирована с помощью SaveFunctionToBuffer.
    • 2 -- производить компиляцию без доступа к внешним функциям и переменным. Это полностью изолирует компилируемую функцию. Нужно, однако, понимать, что блок по-прежнему может косвенно вызывать внешние функции, являющиеся событиями, к примеру, с помощью функции Publish или подобных.

Возвращаемое значение

Возвращает новый объект компилированной функции, который можно исполнить с помощью функций Exec и ExecEx, либо экспортировать в память с помощью SaveFunctionToBuffer.

Примеры

//Пример из статьи ProfilerStart дополняется четвертым тестом с заранее компилированной функцией.

  Function Square(a)
    Exit a*a;
  EndFunction

//Включить режим отладки
DebuggingRights(1);

//Очистить предыдущие результаты профилирования
ProfilerClear;

//Включить профайлер
ProfilerStart;

//Находим разницу во времени выполнения функции разными способами
For i:=1 to 100000 Do
  Square(i);
EndDo;

For i:=1 to 100000 Do
  ExecuteFunction("Square",1,i);
EndDo;

Стр:="Square(i);";
aFunc:=Compile(Стр);
For i:=1 to 100000 Do
  Exec(aFunc);
EndDo;

//Останавливаем профайлер
ProfilerStop;


Период:=dbgHRPCCurrent();
For i:=1 to 100000 Do
  Exec("Square(i)");
EndDo;
Период:=dbgHRPCGetPeriod(Период)/1000000;
Message("Выполнение Exec: "+Период+" мс.");


//Вызываем окно отладчика для просмотра результатов профилирования
DebugBreak;

//Функция DebugBreak не должна быть последней в модуле
Message("Тест выполнен успешно");

//Для i5 на Windows 7 результаты профилирования были следующими:
//* Прямой вызов функции занял 229 мс.
//* Использование функции ExecuteFunction заняло 307 мс.
//* Использование заранее скомпилированной функции заняло 357 мс.
//* Компиляция текста и вызов функции заняли 1181 мс. 
//  Комментарий: компиляция и выполнение уменьшает скорость работы профайлера, так как увеличивается количество исходных текстов в массиве, из которого производится поиск при профилировании
//  Для массива текстов размером в ~10000, профайлер замедляет исполнение примерно в 1.4 раза по сравнению с работой профайлера с пустым массивом (коэффициент можно найти, если переставить местами
//      циклы, включить цикл Exec в профилирование и сравнить результаты). Поэтому, время исполнения последнего цикла было найдено без помощи профайлера.

//Вывод: Для случая заранее скомпилированной функции скорость исполнения для этого примера выше в 3.3 раза по сравнению с компиляцией и исполнением.
//  Для текстов с большим количеством быстро исполняемых инструкций, эта разница будет только возрастать.
//  Скорость исполняемой заранее скомпилированной функции почти не уступает скорости обычного исполнения. См. также статью ProfilerStart