Articles Delphi Performance Tuning – Creating 500 Panels on a Form by Scott Hollows

emailx45

Местный
Регистрация
5 Май 2008
Сообщения
3,571
Реакции
2,438
Credits
573
Delphi Performance Tuning – Creating 500 Panels on a Form
Scott Hollows - 19/Aug/2017
[SHOWTOGROUPS=4,20]
I needed to create 500 panels on a form for a game that I was assisting another person with … and Delphi was choking. It was taking 20 seconds to do this. Not cool. We had to find a way to speed it up. This is what we did …

I trawled through my usual tricks to speed up controls and reduce flickering with no luck. For example, none of these known workarounds improved the performance.

The 500 panels needed to appear on another panel called MainPanel
Код:
procedure TGameForm.FormCreate(Sender: TObject);
begin
 self.ControlStyle := self.ControlStyle + [csOpaque];
 MainPanel.ControlStyle := MyPanel.ControlStyle + [csOpaque];

 self.DoubleBuffered := TRUE;
 MainPanel.DoubleBuffered := TRUE;
 MainPanel.ParentDoubleBuffered := TRUE;
end;

I also tried disabling updates but no joy. It was still slow.
Код:
LockWindowUpdate (MainPanel.Handle);

LockWindowUpdate (0);

I trawled through a smorgasborg of other performance tuning tricks from my collection of code snippets but none of them worked.

Solution – unparent
I finally found a solution and now the panels were created in a split second and were painted on the screen with no lag

The magic trick was to temporary remove the main panel from the form by changing its parent property to nil. That ensured that the screen was not repainted while the 500 panels were being added to it. After re-parenting it back to the form, the screen repainted immediately with no lag.
Код:
procedure TGameForm.FormCreate(Sender: TObject);
begin
  // prevent screen updates by removing the panel from the form
  MainPanel.parent := nil;
  
  MainPanel.parent := self;  // re-enable screen updates
end;

This all happened behind the scenes so the user did not see the panel being temporarily removed. If you try this and the unparent / reparent operations is noticable, try using the DoubleBuffered technique noted above

Good enough
Im sure there are other techniques to achieve this, but this approach was good enough to get the job done so I could move on to other things. If you have other ideas that might work, you are welcome to post them here in a comment


[/SHOWTOGROUPS]