Для начала рассмотрим задачу, стоящую перед разработчиками, использующими Delphi: необходимость измерения времени, затрачиваемого на загрузку формы из DFM файла. Это важно для оптимизации производительности приложения, особенно когда время создания формы составляет значительную часть общего времени отклика приложения.
Проблема и вопрос
В рамках тестирования производительности требуется метод измерения времени, необходимого для загрузки определения формы из DFM. Все формы в проекте наследуют пользовательский класс формы. Для измерения текущего времени требуется переопределение методов как "точек расширения":
Начало процесса десериализации.
После десериализации, что может быть реализовано путем переопределения процедуры Loaded.
Момент непосредственно перед выполнением события OnFormCreate.
Логирование для TMyForm.Create(nil) может выглядеть следующим образом:
00.000 - экземпляр создан
00.010 - перед десериализацией
01.823 - после десериализации
02.340 - перед OnFormCreate
Необходимо определить, какие методы TObject или TComponent лучше всего подходят для измерения времени. Возможно, существуют другие точки расширения в процессе создания формы.
Контекст
В контексте некоторых форм приложения, имеющих простую структуру с использованием компонентов, таких как PageControls и QuantumGrids, было обнаружено, что основное время загрузки уходит на сам процесс создания формы, а не на доступ к базе данных или другие операции в событии OnFormShow. В качестве объекта для сравнения будет создан мокап формы с аналогичной структурой, но без кода и подключений к модулю данных, чтобы измерить время его создания.
Альтернативный ответ
Рассмотрим альтернативный подход, предполагающий, что основное время загрузки формы уходит на десериализацию DFM. Можно добавить конструктор к форме, который будет включать измерение времени до и после наследованного создания формы:
constructor TMyForm.Create( AOwner: TComponent );
var
S, E: Int64;
begin
QueryPerformanceCounter( S );
inherited Create( AOwner ); // здесь происходит десериализация DFM
QueryPerformanceCounter( E );
// Логирование времени с использованием класса и количества тиков QPC.
LogQPCTime( ClassName, E - S );
end;
Подтвержденный ответ
Согласно обсуждению, лучшее место для логирования "экземпляр создан" - это метод TObject.NewInstance.
В Delphi 2009 и выше, для логирования "перед десериализацией" следует использовать метод TCustomForm.InitializeNewForm. Если такой метод недоступен, можно переопределить TCustomForm.CreateNew и измерить время непосредственно перед его возвратом.
Для логирования "после десериализации" действительно подходит метод TComponent.Loaded.
Для "перед OnFormCreate" следует переопределить TObject.AfterConstructor и измерить время непосредственно перед вызовом наследованного метода. Если нужно измерить общее время создания, следует зафиксировать время после возврата наследованного метода, что будет включать время выполнения OnFormCreate и начальную активацию. В качестве альтернативы можно переопределить TForm.DoCreate, если это не переопределено где-либо еще в вашем коде.
Пример кода
constructor TMyForm.Create( AOwner: TComponent );
var
Start, End: Int64;
begin
QueryPerformanceCounter( Start );
inherited Create( AOwner );
QueryPerformanceCounter( End );
// Логируем время создания формы
LogTime( 'Form creation time:', End - Start );
end;
procedure TMyForm.Loaded;
begin
inherited Loaded;
QueryPerformanceCounter( StartTimeAfterDeserialization );
// Логируем время после десериализации
LogTime( 'Time after deserialization:', StartTimeAfterDeserialization - Start );
end;
procedure TMyForm.FormCreate(Sender: TObject);
begin
QueryPerformanceCounter( StartTimeBeforeOnFormCreate );
inherited FormCreate(Sender);
// Логируем время перед OnFormCreate
LogTime( 'Time before OnFormCreate:', StartTimeBeforeOnFormCreate - StartTimeAfterDeserialization );
end;
Где QueryPerformanceCounter - это функция для получения высокоточного времени, а LogTime - это виртуальная функция для логирования времени в микросекундах.
Используя данный подход, разработчики могут точно измерить время, затрачиваемое на различные этапы создания и загрузки формы, что позволит оптимизировать производительность приложения.
Необходимо измерить скорость загрузки формы в Delphi, используя различные методы и события жизненного цикла компонентов для оптимизации производительности приложения.
Комментарии и вопросы
Получайте свежие новости и обновления по Object Pascal, Delphi и Lazarus прямо в свой смартфон. Подпишитесь на наш Telegram-канал delphi_kansoftware и будьте в курсе последних тенденций в разработке под Linux, Windows, Android и iOS