Recent

Author Topic: Any faster code?  (Read 3906 times)

justnewbie

  • Sr. Member
  • ****
  • Posts: 292
Any faster code?
« on: December 27, 2020, 06:00:32 pm »
I need to create 1000 TImages runtime.
My simple code works well, but very very slow.

Code: Pascal  [Select][+][-]
  1. for iC := 1 to 50 do
  2.     for iiC := 1 to 20 do
  3.     begin
  4.       pix[iC, iiC] := TImage.Create(Self);
  5.       pix[iC, iiC].Parent := Panel1;
  6.       pix[iC, iiC].Width := 15;
  7.       pix[iC, iiC].Height := 15;
  8.       pix[iC, iiC].Left := (iiC - 1) * 15;
  9.       pix[iC, iiC].Top := (iC - 1) * 15;
  10.       pix[iC, iiC].Visible := True;
  11.       pix[iC, iiC].Enabled := True;
  12.     end;

Is it possible to make it (much) faster?  ::)

Awkward

  • Full Member
  • ***
  • Posts: 135
Re: Any faster code?
« Reply #1 on: December 27, 2020, 06:15:24 pm »
not to make 1000 TImage?
Or make it when it needs only coz i thinkm you can't show all of them at same time

wp

  • Hero Member
  • *****
  • Posts: 11923
Re: Any faster code?
« Reply #2 on: December 27, 2020, 06:16:12 pm »
What else are you doing? I put your code into the OnCreate method of a form, added time measuring steps and found that the 1000 images are created within 0.008 sec. Even with assigning the appliation icon to each image it only takes 0.1 sec. That not "very, very, slow".

Code: Pascal  [Select][+][-]
  1. procedure TForm1.FormCreate(Sender: TObject);
  2. var
  3.   ic, iic: Integer;
  4.   t: TDateTime;
  5. begin
  6.   t := Now();
  7.   for iC := 1 to 50 do
  8.       for iiC := 1 to 20 do
  9.       begin
  10.         pix[iC, iiC] := TImage.Create(Self);
  11.         pix[iC, iiC].Parent := Panel1;
  12.         pix[iC, iiC].Width := 15;
  13.         pix[iC, iiC].Height := 15;
  14.         pix[iC, iiC].Left := (iiC - 1) * 15;
  15.         pix[iC, iiC].Top := (iC - 1) * 15;
  16.         pix[iC, iiC].Visible := True;
  17.         pix[iC, iiC].Enabled := True;
  18.         pix[iC, iiC].Picture.Assign(Application.Icon);
  19.       end;
  20.   t := Now() - t;
  21.   Caption := FormatDateTime('s.zzz"s"', t);
  22. end;  
On the other hand, when this code is run in the OnClick event handler of a button, when the form is already show, it becomes much slower: 8 seconds. The reason is - probably - that the panel is repainted after adding each new image. An easy (and cross-platform) way to prevent this is to hide the panel before, and to re-show it after inserting the images. (there are certainly more sophisticated and better solutions..., but i did not want to spend too much thinking...)
« Last Edit: December 27, 2020, 06:28:45 pm by wp »

MarkMLl

  • Hero Member
  • *****
  • Posts: 6692
Re: Any faster code?
« Reply #3 on: December 27, 2020, 06:17:39 pm »
Start off by finding out where the bottleneck is. For example, is it the visible/enabled?

MarkMLl
MT+86 & Turbo Pascal v1 on CCP/M-86, multitasking with LAN & graphics in 128Kb.
Pet hate: people who boast about the size and sophistication of their computer.
GitHub repositories: https://github.com/MarkMLl?tab=repositories

justnewbie

  • Sr. Member
  • ****
  • Posts: 292
Re: Any faster code?
« Reply #4 on: December 27, 2020, 06:30:23 pm »
@Awkward: I need all of them at the same time.
@wp: it's strange, for me it takes 6.7 seconds.

jamie

  • Hero Member
  • *****
  • Posts: 6130
Re: Any faster code?
« Reply #5 on: December 27, 2020, 06:34:30 pm »
you are approaching this at the wrong angle..
use a TImageList or use a single image at the sum of the X and Y then in code simply mark it off..

you can display all of them at once because its a single image.

Use a TpaintBox to paint the image and draw on the paint box any bounding boxes etc..

EDIT:

 There are also other alternatives like using the beginFormUpdate, etc...

« Last Edit: December 27, 2020, 06:37:09 pm by jamie »
The only true wisdom is knowing you know nothing

justnewbie

  • Sr. Member
  • ****
  • Posts: 292
Re: Any faster code?
« Reply #6 on: December 27, 2020, 06:44:56 pm »
@wp: yes, the "panel hide/show trick" is not a bad idea, now it is 0.8 sec.
@jamie: I'm not sure what you mean, but the single image is surely not good. It is a puzzle game, and I need to move the images.

wp

  • Hero Member
  • *****
  • Posts: 11923
Re: Any faster code?
« Reply #7 on: December 27, 2020, 06:58:46 pm »
@wp: yes, the "panel hide/show trick" is not a bad idea, now it is 0.8 sec.
I could imagine one issue with "show/hide": When other controls are anchored to the panel they may jump to other locations while the panel is hidden. As a workaround you can place the panel into another equally sized panel which remains visible, and to which you can anchor these controls.

jamie

  • Hero Member
  • *****
  • Posts: 6130
Re: Any faster code?
« Reply #8 on: December 27, 2020, 07:06:24 pm »
@wp: yes, the "panel hide/show trick" is not a bad idea, now it is 0.8 sec.
@jamie: I'm not sure what you mean, but the single image is surely not good. It is a puzzle game, and I need to move the images.

Use a TDrawGrid and custom draw your cells

The only true wisdom is knowing you know nothing

Awkward

  • Full Member
  • ***
  • Posts: 135
Re: Any faster code?
« Reply #9 on: December 27, 2020, 07:18:49 pm »
@Awkward: I need all of them at the same time.
@wp: it's strange, for me it takes 6.7 seconds.
TImage? not TPicture?

Handoko

  • Hero Member
  • *****
  • Posts: 5158
  • My goal: build my own game engine using Lazarus
Re: Any faster code?
« Reply #10 on: December 27, 2020, 07:33:20 pm »
@justnewbie

Are you writing a computer game?

If yes then don't use TImage. It is okay for very simple games, like Tetris or Tic-Tac-Toe but soon you will know it is slow. You can check the wiki or search the forum for better graphics libraries.

Maybe you haven't know, let me tell you a little secret that all game programmers should already know. It usually has better performance if you draw all the graphics at once to the screen. That means you should a buffer or some call it virtual screen. Doing it also will fix flickering effect that may happen if there are too many items need to be drawn.
You can read more here:

https://forum.lazarus.freepascal.org/index.php/topic,38136.msg263143.html#msg263143

justnewbie

  • Sr. Member
  • ****
  • Posts: 292
Re: Any faster code?
« Reply #11 on: December 27, 2020, 07:45:53 pm »
Use a TDrawGrid and custom draw your cells

I need to move the images with the mouse.

justnewbie

  • Sr. Member
  • ****
  • Posts: 292
Re: Any faster code?
« Reply #12 on: December 27, 2020, 07:47:41 pm »
@justnewbie

Are you writing a computer game?

If yes then don't use TImage. It is okay for very simple games, like Tetris or Tic-Tac-Toe but soon you will know it is slow. You can check the wiki or search the forum for better graphics libraries.

Maybe you haven't know, let me tell you a little secret that all game programmers should already know. It usually has better performance if you draw all the graphics at once to the screen. That means you should a buffer or some call it virtual screen. Doing it also will fix flickering effect that may happen if there are too many items need to be drawn.
You can read more here:

https://forum.lazarus.freepascal.org/index.php/topic,38136.msg263143.html#msg263143
Thank you Handoko, I will check it out.

Handoko

  • Hero Member
  • *****
  • Posts: 5158
  • My goal: build my own game engine using Lazarus
Re: Any faster code?
« Reply #13 on: December 28, 2020, 05:25:38 pm »
Quote
It's strange. This code below should give a random list without repeated items. But, it gives repeated values. Why?

Are you sure? How did test it?

By using this code below, I can see there were no repeating number:

Code: Pascal  [Select][+][-]
  1.   S := '';
  2.   for iC := 0 to resolution-1 do
  3.     S := S + randX[iC].ToString + LineEnding;
  4.   ShowMessage(S);

justnewbie

  • Sr. Member
  • ****
  • Posts: 292
Re: Any faster code?
« Reply #14 on: December 28, 2020, 05:38:31 pm »
Quote
It's strange. This code below should give a random list without repeated items. But, it gives repeated values. Why?

Are you sure? How did test it?

By using this code below, I can see there were no repeating number:

Code: Pascal  [Select][+][-]
  1.   S := '';
  2.   for iC := 0 to resolution-1 do
  3.     S := S + randX[iC].ToString + LineEnding;
  4.   ShowMessage(S);

Yes, the code was good, the silly post removed. Thanks Handoko for the feedback!

 

TinyPortal © 2005-2018