Recent

Author Topic: Quicker way to update TMemo  (Read 1042 times)

johnmc

  • New Member
  • *
  • Posts: 47
Quicker way to update TMemo
« on: September 01, 2022, 01:14:24 pm »
I was testing a sort routine and have a form that generates some random strings and displays them in a TMemo. I can read this into an array of strings and sort it. Redisplaying the sorted array is very slow. Is there a quick way to update the TMemo. I am using:

Code: Pascal  [Select][+][-]
  1.  
  2.   Memo1.lines.Clear;
  3.   Memo1.Visible:=False;
  4.   for I := low(aStrArry) to high(aStrArry) do
  5.   begin
  6.     Memo1.append(aStrArry[I]);
  7.   end;
  8.   Memo1.Visible:=True;
  9.  
  10.  

This takes nearly 7mins without the Visible False/True, but reduces to a few seconds when used for 100000 50 Character strings.

Regards John

marcov

  • Administrator
  • Hero Member
  • *
  • Posts: 11383
  • FPC developer.
Re: Quicker way to update TMemo
« Reply #1 on: September 01, 2022, 01:21:14 pm »
Code: [Select]
Memo1.lines.beginupdate;
 Memo1.lines.Clear;
  Memo1.Visible:=False;
  for I := low(aStrArry) to high(aStrArry) do
  begin
    Memo1.append(aStrArry[I]);
  end;
 Memo1.lines.endupdate;
  Memo1.Visible:=True;

But memos are user interface elements, not datastructures, and very large datasets are not really optimal.
 

jamie

  • Hero Member
  • *****
  • Posts: 6090
Re: Quicker way to update TMemo
« Reply #2 on: September 01, 2022, 01:23:09 pm »
Use memo.lines.assign
The only true wisdom is knowing you know nothing

johnmc

  • New Member
  • *
  • Posts: 47
Re: Quicker way to update TMemo
« Reply #3 on: September 01, 2022, 03:05:22 pm »

But memos are user interface elements, not datastructures, and very large datasets are not really optimal.
 

Point noted.  :)

It is also recomended to put the beginupdate endupdate in a try ... finally ... end block.
 
I must RTM.

Regards John

Thaddy

  • Hero Member
  • *****
  • Posts: 14201
  • Probably until I exterminate Putin.
Re: Quicker way to update TMemo
« Reply #4 on: September 01, 2022, 03:59:25 pm »
Use memo.lines.assign
That still needs:
Code: Pascal  [Select][+][-]
  1. memo.lines.beginupdate;
  2. memo.lines.assign(< some Tstrings> );
  3. memo.lines.endupdate;
to be optimal.
Much faster you can not realistically get with clean code and such a data load.
Note the above code does not need the memo to be hidden at all.
« Last Edit: September 01, 2022, 04:01:59 pm by Thaddy »
Specialize a type, not a var.

ASerge

  • Hero Member
  • *****
  • Posts: 2222
Re: Quicker way to update TMemo
« Reply #5 on: September 01, 2022, 04:40:35 pm »
Is there a quick way to update the TMemo. I am using:
In Windows, the fastest way is memo.Text := lines.Text;

johnmc

  • New Member
  • *
  • Posts: 47
Re: Quicker way to update TMemo
« Reply #6 on: September 01, 2022, 07:07:35 pm »
Use memo.lines.assign


I think that would require me to convert from my Array of Strings to TStringList.

I will have a think about whether to use TStringList instead.

rvk

  • Hero Member
  • *****
  • Posts: 6111
Re: Quicker way to update TMemo
« Reply #7 on: September 01, 2022, 07:17:53 pm »
I think that would require me to convert from my Array of Strings to TStringList.
Yes. Why are your strings in an array anyway?
Putting them in a TStringList from the beginning is much easier (depending on where they come from).

I can read this into an array of strings and sort it.
BTW. TStringList also has a sort option.

MarkMLl

  • Hero Member
  • *****
  • Posts: 6676
Re: Quicker way to update TMemo
« Reply #8 on: September 01, 2022, 08:28:20 pm »
I think there's one fundamental rule: add as much per operation as possible. Hence references to lines.Text := and lines.Assign() etc.

That's particularly important with visual components (e.g. TMemo), and vitally important if a component is visible.

However, you (OP) also mention an array of strings: if this is a dynamic array you /really/ do not want to be appending individual strings (i.e. increasing the list by one each time) since each change of size implies some level of background memory management; it's far more efficient to increase it by some larger amount and then to fill in the elements by indexed assignment.

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

mas steindorff

  • Hero Member
  • *****
  • Posts: 532
Re: Quicker way to update TMemo
« Reply #9 on: September 01, 2022, 09:12:20 pm »
I ran into the same issue when I was trying to update a Tmemo with a lot of Real time data.
My fix was to store the strings in a TStringList "MemoStrBuf" and then use a timer @1/3 of a second to move the buffered strings to the memo using the Memo.lines.AddStrngs(from my buffer).
I like to see the latest info on the screen (the end of the memo) so I needed to break this into two steps.
 1st I grab the latest str from my buffer:
str := MemoStrBuf[MemoStrBuf.count-1];
 then delete it from the buffer with a .Delete[same index]
  then I update the memo with memo1.Lines.AddStrings(MemoStrBuf)
  then to get the memo to jump to the end with memo1.lines.Add(str)
followed by house cleaning like memoStrBuf.clear and time reenableing...

I've also found the system is slow down if the memo starts to get a large number of strings in it. in my case a few thousand lines. In this case you should consider limiting its count.  again it's best to remove a batch of lines at a time.  I figure removing 1 seconds worth of strings once I have 120 seconds of data ( 500 out of 60,000 strings) but I also have UI controls to change these settings when I run on slower computers.
MAS
 
windows 10 &11, Ubuntu 21+ - fpc 3.0.4, IDE 2.0 general releases

MarkMLl

  • Hero Member
  • *****
  • Posts: 6676
Re: Quicker way to update TMemo
« Reply #10 on: September 01, 2022, 09:38:01 pm »
I agree. Put the number of lines to be retained in a .ini file or something... and only delete a chunk of lines when you get to that count + (say) 128 since deletion from the start will be expensive.

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

 

TinyPortal © 2005-2018