Board index » delphi » Speed of creating tGraphicControl at runtime

Speed of creating tGraphicControl at runtime


2005-05-19 01:51:43 AM
delphi54
Creating at runtime multiple instances of a descendant of tGraphicControl
seems very slow.
I've traced this to the point where the Parent property is set. There's a
chunk of complicated-looking code in in tWinControl.SetParent which is
missed out if csReading in ComponentState, but ComponentState is read-only
so I can not set it in my component.
What's the best way of speeding this up? My components do not need to move
or resize or anything complicated, but I need an awful lot which just sit
there and redraw themselves when necessary.
Thanks,
Don Taylor.
 
 

Re:Speed of creating tGraphicControl at runtime

Sorry, that should be tWinControl.InsertControl, which tests csReading in
aControl.ComponentState.
 

Re:Speed of creating tGraphicControl at runtime

"Don Taylor" <XXXX@XXXXX.COM>writes
Quote
What's the best way of speeding this up? My components do not need to
move or resize or anything complicated, but I need an awful lot which just
sit there and redraw themselves when necessary.
Do you really need actual controls? Try doing it with a single graphic on
your display, and just updating areas of your larger graphic as needed.
Create a structure in your app to track the logic of what graphics goes
where in the big graphic.
 

Re:Speed of creating tGraphicControl at runtime

Yep, lots of alternatives considered - unfortunately the appearance and
position of many of these controls have to be calculated (before form
creation) depending on user and application options - a single big bitmap
would be extremely complicated.
Lets face it, for the app I am developing, VCL controls are absolutely
stonkingly ideal and brilliantly simple to use. it is just a shame the
bridge to Windows GDI is clearly processor greedy. This app is being ported
from BPW 7 where I used similar (but less brilliantly simple) visual
components of my own design. This was much, much faster than Delphi 7, but
I can only generate 16-bit apps with it. We now need 32-bit apps to run on
XP, but we'll have trouble convincing users to upgrade if it clearly runs a
lot slower!
Thanks for your comments.
Don.
"GrandmasterB" <XXXX@XXXXX.COM>writes
Quote
"Don Taylor" <XXXX@XXXXX.COM>writes
news:428b80a9$XXXX@XXXXX.COM...
>What's the best way of speeding this up? My components do not need to
>move or resize or anything complicated, but I need an awful lot which
>just sit there and redraw themselves when necessary.

Do you really need actual controls? Try doing it with a single graphic
on your display, and just updating areas of your larger graphic as needed.
Create a structure in your app to track the logic of what graphics goes
where in the big graphic.



 

Re:Speed of creating tGraphicControl at runtime

Don Taylor writes:
Quote
Yep, lots of alternatives considered - unfortunately the appearance
and position of many of these controls have to be calculated (before
form creation) depending on user and application options - a single
big bitmap would be extremely complicated.

Lets face it, for the app I am developing, VCL controls are absolutely
stonkingly ideal and brilliantly simple to use. it is just a shame
the bridge to Windows GDI is clearly processor greedy. This app is
being ported from BPW 7 where I used similar (but less brilliantly
simple) visual components of my own design. This was much, much
faster than Delphi 7, but I can only generate 16-bit apps with it.
We now need 32-bit apps to run on XP, but we'll have trouble
convincing users to upgrade if it clearly runs a lot slower!
Could you post some code. Then we might have better suggestions.
--------------
Joe Bain
www.iegsoftware.com
 

Re:Speed of creating tGraphicControl at runtime

"Joe Bain" <XXXX@XXXXX.COM..c.o.m>writes
Quote
Could you post some code. Then we might have better suggestions.
Constructor tMyGraphicControl.Create(aOwner: tForm; x, y, w, h: integer);
{override}
Begin
inherited Create(aOwner);
Left := x;
Top := y;
Width := w;
Height := h;
Parent := aOwner; {this takes a relatively long time}
End;
When I say a relatively long time, I mean that if you create a hundred of
these, it might take two or three seconds.
If you miss out the last line, it is virtually instant, although of course
you can not see the created components. it is not the painting slowing it down
either - once created, repainting the form is fairly quick.
Thanks if you can help further.
Don.
 

Re:Speed of creating tGraphicControl at runtime

Don Taylor writes:
Quote
"Joe Bain" <XXXX@XXXXX.COM..c.o.m>wrote in
message news:428c8d86$XXXX@XXXXX.COM...
>Could you post some code. Then we might have better suggestions.

Constructor tMyGraphicControl.Create(aOwner: tForm; x, y, w, h:
integer); {override}
Begin
inherited Create(aOwner);
Left := x;
Top := y;
Width := w;
Height := h;
Parent := aOwner; {this takes a relatively long time}
End;

When I say a relatively long time, I mean that if you create a
hundred of these, it might take two or three seconds.

If you miss out the last line, it is virtually instant, although of
course you can not see the created components. it is not the painting
slowing it down either - once created, repainting the form is fairly
quick.

Thanks if you can help further.

Don.
Can you show the method where the control is acutally painted.
--
--------------
Joe Bain
www.iegsoftware.com
 

Re:Speed of creating tGraphicControl at runtime

"Joe Bain" <XXXX@XXXXX.COM..c.o.m>writes
Quote
Can you show the method where the control is acutally painted.
As I said, the painting is not the issue. Even with no painting at all they
still take a long time to create.
Don.
 

Re:Speed of creating tGraphicControl at runtime

I think it is the painting that is taking the time. If you don't set
the parent the control never gets painted the following code takes
250ms to run, but the form takes 3 more seconds to show because of the
painting code.
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls,
Forms,
Dialogs, StdCtrls;
type
TMyButton = class(TButton)
public
Constructor Create(aOwner: tForm; x, y, w, h:integer);overload;
end;
TForm3 = class(TForm)
private
{ Private declarations }
public
constructor Create(AOwner: TComponent); override;
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
{ TMyButton }
constructor TMyButton.Create(aOwner: tForm; x, y, w, h: integer);
begin
inherited Create(aowner);
Left := x;
Top := y;
Width := w;
Height := h;
Parent := aOwner;
end;
{ TForm3 }
constructor TForm1.Create(AOwner: TComponent);
var x,y:integer;
tc:Cardinal;
begin
inherited;
tc := GetTickCount;
for x := 0 to 50 do
for y := 0 to 20 do
TMyButton.Create(self,x*10,y*10,10,10);
showmessage(IntToStr(GetTickCount-tc));
end;
end.
--------------
Joe Bain
www.iegsoftware.com
 

Re:Speed of creating tGraphicControl at runtime

"Joe Bain" <XXXX@XXXXX.COM..c.o.m>writes
Quote
I think it is the painting that is taking the time. If you don't set
the parent the control never gets painted the following code takes
250ms to run, but the form takes 3 more seconds to show because of the
painting code.
Yes, but it is not the actual contents of the Paint procedure which is slow,
it's whatever Delphi is doing to enable painting on the form for that
control (moving it onto the form if you like). This is not terribly
surprising - clearly there is a lot of hidden maintenance to do - but I was
wondering if anyone knows a way of speeding it up. The performance is
orders of magnitude faster without the VCL encapsulation so clearly it is not
a Windows or hardware limitation.
Don.
 

Re:Speed of creating tGraphicControl at runtime

Then the only thing I could suggest is to do all your drawing to a bmp
and paint it to the form.
--------------
Joe Bain
www.iegsoftware.com
 

Re:Speed of creating tGraphicControl at runtime

I've made a substantial improvement by overriding the parent form's
AlignControls method.
Since my controls don't move, AlignControls is not required.
In the source for tWinControl in Delphi 7 (Controls.pas), InsertControl
calls AlignControl which then calls AlignControls. This reads every
existing control to see if its Align <>alNone. This happens every time you
add a control so the more controls you add, the worse it gets. Adding 400
controls means reading all the Aligns 399+398+397+396...+1 times, even if
they all = alNone. Yuck.
Fortunately, tWinControl.AlignControls is virtual, so it can be overridden
to do nothing. This reduces the time taken to create 400 controls from
1500ms downto 70ms! Well worth doing if no controls use Align.
Don.
"Don Taylor" <XXXX@XXXXX.COM>writes
Quote
Creating at runtime multiple instances of a descendant of tGraphicControl
seems very slow.

I've traced this to the point where the Parent property is set. There's a
chunk of complicated-looking code in in tWinControl.SetParent which is
missed out if csReading in ComponentState, but ComponentState is read-only
so I can not set it in my component.

What's the best way of speeding this up? My components do not need to
move or resize or anything complicated, but I need an awful lot which just
sit there and redraw themselves when necessary.

Thanks,

Don Taylor.


 

Re:Speed of creating tGraphicControl at runtime

In article <428cb881$XXXX@XXXXX.COM>, Don Taylor writes:
Quote
I've made a substantial improvement by overriding the parent form's
AlignControls method.
Not needed, you can simply call the parents DisableAlign when you start
creating your controls, and EnableAlign when you are done.
Peter Below (TeamB)
Use the newsgroup archives :
www.mers.com/searchsite.html
www.tamaracka.com/search.htm
groups.google.com
www.prolix.be
 

Re:Speed of creating tGraphicControl at runtime

"Peter Below (TeamB)" <XXXX@XXXXX.COM>writes
Quote
Not needed, you can simply call the parents DisableAlign when you start
creating your controls, and EnableAlign when you are done.
Thanks Peter, I knew there'd be a simple solution. I have been experimenting
for days. Are there any further ways of speeding up runtime creation?
Perhaps I should RTFM. Except it doesn't quite say "do this to make it
quicker", and sometimes it is hard to track down the time-consuming code,
especially if its in a standard Delphi unit.
BPW used to have a Profiler, which reported timings for whatever blocks of
code you're interested in. Anyone heard of something similar available for
Delphi?
Thanks again,
Don.
 

Re:Speed of creating tGraphicControl at runtime

Don Taylor writes:
Quote

BPW used to have a Profiler, which reported timings for whatever
blocks of code you're interested in. Anyone heard of something
similar available for Delphi?
GPProfile by Primoz Gabrijelcic - instrumenting profiler (modifies the
source code), freeware for D2 - D5, don't know if it exists for later
versions: 17slon.com/gp/gpprofile/
Eric Grange's sampling profiler, tinyurl.com/7twt7 or spelled out
www.google.se/groups&lr=&selm=425102d1%40newsgroups.borland.com&rnum=1
--
Anders Isaksson, Sweden
BlockCAD: web.telia.com/~u16122508/proglego.htm
Gallery: web.telia.com/~u16122508/gallery/index.htm