Delphi Performance Tuning – Creating 500 Panels on a Form

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

+1 this post

Please help get this blog listed on DelphiFeeds by +1 voting here on DelphiFeeds
and also vote on BeginEnd.  Thank you

About Me

scott_hollows_201611

  • Oracle & Delphi software developer based in Perth, Western Australia
  • Australian Delphi User Group – President
  • Australian Oracle User Group – WA Committee Member
  • Available to do remote presentations to user groups on Delphi and Oracle topics
blog email linkedinlogo

 

Published by

5 responses to “Delphi Performance Tuning – Creating 500 Panels on a Form”

  1. Why not send a windows message disable redraw?

  2. This works fine… so long as your child controls don’t draw to the control’s canvas during the process when the parent is nil (e.g. calls Canvas.FillRect) If you need to do this with a control that does that sort of thing during the time the parent is nil, verify Self.HandleAllocated before drawing to the canvas.

  3. Using LockWindowUpdate isn’t recommended – see Raymatond Chan’s OldNewThing blog for details. https://social.msdn.microsoft.com/search/en-US?rq=site%3Ablogs.msdn.microsoft.com%2Foldnewthing&rn=oldnewthing&ral=1&query=lockwindowupdate

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: