views:

227

answers:

2

For performance tests I need a way to measure the time needed for a form to load its definition from the DFM. All existing forms inherit a custom form class.

To capture the current time, this base class needs overriden methods as "extension points":

  1. start of the deserialization process
  2. after the deserialization (can be implemented by overriding the Loaded procedure)
  3. the moment just before the execution of the OnFormCreate event

So the log for TMyForm.Create(nil) could look like:

- 00.000 instance created
- 00.010 before deserialization
- 01.823 after deserialization
- 02.340 before OnFormCreate

Which TObject (or TComponent) methods are best suited? Maybe there are other extension points in the form creation process, please feel free to make suggestions.

Background: for some of our app forms which have a very basic structure (with some PageControls and QuantumGrids) I realized that it is not database access and other stuff in OnFormShow but the construction which took most of the time (around 2 seconds) which makes me wonder where this time is spent. As a reference object I will also build a mock form which has a similar structure but no code or datamodule connections and measure its creation time.

+1  A: 

Let's assume that the loading of the form's DFM is the main time part of the construction of the form, we could add a constructor to the form like:

constructor TMyForm.Create( AOwner: TComponent );
var
    S, E: Int64;
begin
  QueryPerformanceCounter( S );
  inherited Create( AOwner ); // here is the dfm loading
  QueryPerformanceCounter( E );
  // Log using the classname and the time in QPC ticks.
  LogQPCTime( ClassName, E - S );
end;
Ritsaert Hornstra
I'm assuming QueryProformanceCounter() is the paid subscription version of QueryPerformanceCounter()?
Paul-Jan
@Paul-Jan: whoops, now with the non paid subscription version ;).
Ritsaert Hornstra
+3  A: 

The best place for "instance created" is TObject.NewInstance.

In Delphi 2009 the best place for "before deserialization" is TCustomForm.InitializeNewForm. If that isn't available override TCustomForm.CreateNew and grab the time immediately before it returns.

You're correct that the best place for "after deserialization" is TComponent.Loaded.

For "before OnFormCreate" override TObject.AfterConstructor and get the time immediately before calling the inherited method. If you want the total construction time, grab the final time after that inherited call returns. That will include both the OnFormCreate and any initial activation time. Alternatively, you could just override TForm.DoCreate, if you're not overriding that anywhere else.

Craig Peterson