Forum > LCL

[SOLVED] 2.2 win x64: ugly issue with virtual listview "Selected" performance

(1/8) > >>

d7_2_laz:
First of all: after recompilaton of two bigger progs prviously ported from Delphi 7 with 2.2 RC2 Win x64 i encountered nearly no problems. Many compliments to the developers here, that is impressive! And many thanks from my side!

Except those two issues with the virtual listview that, introduced with RC1, - unfortunately - still do not have any status at all.

Those issues do persist:

(1) Virtual listview, MultiSelect: early reference to Selected object may cause performace problems
https://gitlab.com/freepascal.org/lazarus/lazarus/-/issues/39324
-> This issue kills the performance of my prog completely, it breaks long existing code without any need. Only solution so far is a workaround.
Remark: within the test project, the guilty statemant might appear to be very obvious. I intended that of course. But, how to determine what is a good place and what a wrong place?
In reality, the reference to "Selected" or similar within some subordinary routines might be somewhere in the code. And so it might be very hard to find out why all slows down.
A simple "if Selected" at the wrong place, and .. boom, the virtual listview behaves just the contrary as "virtual", as it immediately instantiates all objects at once. The culprit may be deep in the code. No fun at all to rewrite parts of the app only due to this shortly arriving issue.

(2) Virtual listview, MultiSelect: problem: only one item in the list: after click on empty space this single item keeps to stay selected
https://gitlab.com/freepascal.org/lazarus/lazarus/-/issues/39325
-> This issue results in wrong effects when doing owner drawing. Items may appear to be selected ... although they aren't.
Remark: for a solution, i'd recommend to avoid expensive loops around all items for to do a correction of the property.

I would be very happy to see at least somwthing like a status on the issues. Would this be possible?
For information i attach my workaround (based on RC2) here that lets the program behave as expected again.

The good news is: except those two ugly beasts no problems at all with RC2 so far!

d7_2_laz:
Best congratulations for the excellent 2.2! (i like to wokr with Lazarus a lot)
Nearly no problems at all  ... except those remaining two (win x64):

No change here with 2.2, same as newly introduced with RC1 and RC2:

Virtual listview, MultiSelect: early reference to Selected object may cause performance problems
https://gitlab.com/freepascal.org/lazarus/lazarus/-/issues/39324

The only thing i'd like to have is to be downward-compatible about basic objects and properties.
So that one can refer to "Selected" (or "SelCount") anywhere within the code.
Without time-consuming loops around all items - and without (and this is even more worse:) all items of the list are unintendedly instantiated at once bulk-wise!


--- Code: Pascal  [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---  ListView1.Items.Count := 20000;  // Probably somewhere later, but for demo in its elementary form here:  if ListView1.Selected = nil then   -> boom! 20000 items will be instantiated at once, destroying virtualism  // Just saw that it is the same with "SelCount":  if ListView1.SelCount > 0 then     -> boom! all 20000 items will be instantiated at once
"Ugly", because the instantiating "Selected" (or "SelCount") might be located anywhere.
For instance in some multi-called helper routines. Hard to find out what's going on here and old code breaks! Initially it did drive me crazy
until i found out what caused the drastic performance decrease in my app.
Remark: the windows folder "C:\Windows\WinSxS" does contain nearly 20000 items. that was causing my observation.
Question: how to decide under which circumstances one can refer to
"Selected" or "SelCount" without harm??

The problem did not exist with 2.0.12 and before, but with 2.2 RC1, 2.2 RC2 and 2.2.

Virtual listview, MultiSelect: problem: having only one item in the list: after click on empty space this single item keeps to stay selected
https://gitlab.com/freepascal.org/lazarus/lazarus/-/issues/39325

After clicking on empty area, it should be possible to rely on the last item correctly being de-selected.
For instance for to achieve correct owner-drawing if one use that for specific paint of selected objects!
Imo, the evaluation should be done best without time-expensive loops along all 50000 items.

I'd highly wish to see, after four months, at least something like a status resp. label on these issues so that there is an indication that they don't will get forgotten.

ASerge:

--- Quote from: d7_2_laz on January 15, 2022, 01:07:15 pm ---
--- Code: Pascal  [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---  ListView1.Items.Count := 20000;  // Probably somewhere later, but for demo in its elementary form here:  if ListView1.Selected = nil then   -> boom! 20000 items will be instantiated at once, destroying virtualism  // Just saw that it is the same with "SelCount":  if ListView1.SelCount > 0 then     -> boom! all 20000 items will be instantiated at once
--- End quote ---
Windows 7 x64, Lazarus 2.2.0
Form with ListView (OwnerData=True, ViewStyle=vsReport, 2 columns), Memo and two buttons:

--- Code: Pascal  [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---procedure TForm1.Button1Click(Sender: TObject);begin  ListView1.Items.Count := 20000;end; procedure TForm1.Button2Click(Sender: TObject);begin  if ListView1.Selected = nil then    Memo1.Append('nil');end; procedure TForm1.ListView1Data(Sender: TObject; Item: TListItem);var  S: string;begin  S := IntToStr(Item.Index);  Memo1.Append(S); // Logging of requested items  Item.Caption := S;  Item.SubItems.Append(S + ' ' + S);end;After pressing Button1, only visible elements are requested. After pressing Button2 - not one at all.

d7_2_laz:
Hello ASerge,

many thanks for your reply!
Unfortunately that's not the point.
Could you
- set the ListView to "MultiSelect" (problem only here)
- and move your lines 8 and 9 (if ListView1.Selected = nil  etc.) directly after line3?    (but this is meant only as a simple demo)
What do you see how many items are initialized at once?

My testcases are placed within the issue reports.

ASerge:

--- Quote from: d7_2_laz on January 15, 2022, 02:50:49 pm ---Could you
- set the ListView to "MultiSelect" (problem only here)

--- End quote ---
You're right. After that, when press Button 2, all the elements are requested.
But if I change (ListView1.Selected = nil) to (ListView1.SelCount = 0) no items requested. In this case, a call is made via the widget without iterating over the elements.

Navigation

[0] Message Index

[#] Next page

Go to full version