Large Listbox Load Perf Q.

Hi everyone,

I am trying to fine tune an app of mine and I am running into a listbox add row performance issue. I am hoping that I can still optimize my code (i have spent much time on this and have optimized my code substantially in other areas).

As you can see I have 5 columns and It is taking 22.53 seconds to only load 524,288 entries. The largest load that I will need to load is a little over 4 million entries.

My calculation functions are separate from the function that loads my listbox. Here is the function that is iterating through a 2D array to load this.

for i = 0 to subnets-1 MainWindow.SubnetRangeListbox.AddRow(Str(MainWindow.SubnetRangeListbox.LastIndex+2),Array_DecRangeInfo(i,0),Array_DecRangeInfo(i,1),Array_DecRangeInfo(i,2),Array_DecRangeInfo(i,3))
MainWindow.SubnetRangeListbox.CellTag(MainWindow.SubnetRangeListbox.Lastindex,1) = Str(Array_DecRangeInfo(i,0))
MainWindow.SubnetRangeListbox.CellTag(MainWindow.SubnetRangeListbox.Lastindex,2) = Str(Array_DecRangeInfo(i,1))
MainWindow.SubnetRangeListbox.CellTag(MainWindow.SubnetRangeListbox.Lastindex,3) = Str(Array_DecRangeInfo(i,2))
MainWindow.SubnetRangeListbox.CellTag(MainWindow.SubnetRangeListbox.Lastindex,4) = Str(Array_DecRangeInfo(i,3))
Next i

Knowing that I can’t thread enable this function am I just stuck? I noticed other applications that are simialar to mine that are written in ObjC can load their listbox instantly for the 4mil entries, but I don’t have their code to understand how they wrote it.

Up to this point I have deployed a lazy load and I relied on the user only using the mouse wheel which worked just fine. However I had to add a scroll bar and that changed the dynamics a bit since the mouse wheel scrolls down a lot slower than a user dragging a scroll bar down fast,which breaks my lazy load.

Any ideas would be much appreciated.

Thank you :slight_smile:

Mike… DON’T do that :frowning:
Figure out a paging algorithm… load a few screen fulls at a time…

I have an app at work that needs to show 100,000 providers (worst case)… but it only loads like 100 at a time (I wrote the back end, the paging is done in a webapp)

[quote=109642:@Dave S]Mike… DON’T do that :frowning:
Figure out a paging algorithm… load a few screen fulls at a time…

I have an app at work that needs to show 100,000 providers (worst case)… but it only loads like 100 at a time (I wrote the back end, the paging is done in a webapp)[/quote]
Dave I am already doing that with my Lazy Load functions which again works great until I added the scrollbar. I have been loading 6000 records per second and that was fine when my users used the mousewheel to scroll through all of the entries. The issue I have is that with the scrollbar now a user can drag all the way to the bottom VERY FAST and my lazy load can’t keep up…

Perhaps I am missing something on the scrollbar to control the speed of how fast a user can scroll down?

Mike, How much time does the loop take if you comment out the CellTag assignments? Then, what if you just add a blank row? I.e. nix the calls to Str() in AddRow.

BTW I also have this above my loop.

  #pragma BackgroundTasks false
  #pragma BoundsChecking false
  #pragma NilObjectChecking false
  #pragma StackOverflowChecking false
  #pragma DisableBackgroundTasks

After commenting out the Celltag entries I have 10.28 seconds for the same 524,288 entries.

After just addrow “” removing the strings I get 1.97 seconds which would be ideal If I had the data.

Its is becoming more evident that I can’t load 4 mil entries in a second or two so the Lazy Load is my only option.

So my next question on this is how do I control the Scrollbar to only scroll as fast as say the mouse wheel for example?

So nix the Str() calls in AddRow… If that cuts things to under a second, you could override CellBackgroundPaint and CellTextPaint to stuff the text in as needed, and return false so default painting can take place. If it doesn’t, you might look at Studio Stable Graphics listbox. I’m pretty sure it can just define 500K rows nearly instantaneously.

Brad can we do 4 million close to instant with SS Listbox?

I include this pragma and it seems to help:

#pragma PleaseSpeedUpGoGoGo

The pragma with 4 “Go’s” has been deprecated, don’t use that. =) The 3 Go version is optimized.

(j/k)

Maybe this is obvious, with the ScrollBar there’s the Live setting where Scroll is done realtime. I’ve found I’ve had to sadly do away with this sort of thing to get proper performance. Where the user has to release the mouse to see the new “window” of entries to display.

I’ve come to think this is the tradeoff of lists in general. I wonder though… for email I use a very old version of Eudora (the last version), and that can have lists that are enormous and yet the populate lightening-fast and scroll without any care in the world.

[quote=109650:@Mike Cotrone]Brad can we do 4 million close to instant with SS Listbox?
[/quote]

I’d have to look and test. I was happy with several thousand rows at a time when I built it :-).

Eh, the current release doesn’t have the rowCount setter. Grrrrrrr. My bad. Mike, I’ll be back with more information on this later today.

I would want to add that if you set listbox to visible = false while loading, you avoid some redrawing.

Also if I see this code:

MainWindow.SubnetRangeListbox.AddRow(Str(MainWindow.SubnetRangeListbox.LastIndex+2),Array_DecRangeInfo(i,0),Array_DecRangeInfo(i,1),Array_DecRangeInfo(i,2),Array_DecRangeInfo(i,3)) MainWindow.SubnetRangeListbox.CellTag(MainWindow.SubnetRangeListbox.Lastindex,1) = Str(Array_DecRangeInfo(i,0)) MainWindow.SubnetRangeListbox.CellTag(MainWindow.SubnetRangeListbox.Lastindex,2) = Str(Array_DecRangeInfo(i,1)) MainWindow.SubnetRangeListbox.CellTag(MainWindow.SubnetRangeListbox.Lastindex,3) = Str(Array_DecRangeInfo(i,2)) MainWindow.SubnetRangeListbox.CellTag(MainWindow.SubnetRangeListbox.Lastindex,4) = Str(Array_DecRangeInfo(i,3))

you made something wrong.
Please make local variable for the listbox, so you don’t query the window each time and let it look for th elistbox.
Next don’t use str() here at all. it’s a variant, so any conversion needed will be done automatically.
And cache the last index value, please.

Maybe like this:

dim l as listbox = MainWindow.SubnetRangeListbox. l.AddRow(Str(MainWindow.SubnetRangeListbox.LastIndex+2),Array_DecRangeInfo(i,0),Array_DecRangeInfo(i,1),Array_DecRangeInfo(i,2),Array_DecRangeInfo(i,3)) dim row as integer = l.lastindex l.CellTag(row,1) =(Array_DecRangeInfo(i,0)) l.CellTag(row,2) =(Array_DecRangeInfo(i,1)) l.CellTag(row,3) =(Array_DecRangeInfo(i,2)) l.CellTag(row,4) =(Array_DecRangeInfo(i,3))

Well, I can get you 1M rows in 9 sec (Mac, 2.5 GHz i5). Memory allocation for each row/cell is killing this. Hmmmm.

Thanks Christian, but that really doesn’t buy me much performance, plus it looks weird to the user :slight_smile:

[quote=109683:@Christian Schmitz]Maybe like this:

dim l as listbox = MainWindow.SubnetRangeListbox. l.AddRow(Str(MainWindow.SubnetRangeListbox.LastIndex+2),Array_DecRangeInfo(i,0),Array_DecRangeInfo(i,1),Array_DecRangeInfo(i,2),Array_DecRangeInfo(i,3)) dim row as integer = l.lastindex l.CellTag(row,1) =(Array_DecRangeInfo(i,0)) l.CellTag(row,2) =(Array_DecRangeInfo(i,1)) l.CellTag(row,3) =(Array_DecRangeInfo(i,2)) l.CellTag(row,4) =(Array_DecRangeInfo(i,3))[/quote]
Very much appreciated Christian! I will make these changes and try. Thank you

To be honest I’d stuff all this in a db (just in memory even)
Then use something like Kems data on demand listbox or einhugurs data grid to page it
Putting millions of rows IN the listbox will be a memory hog and it will be slower than paging it

Thanks Norman. I wrote my own pagination function a while back which has been working great. I just am running into a snag with trying to better control the scrollbar speed. I had to use a scrollbar control instance in leiu of the Listbox scroll bar due to the paging. When using the Mousewheel it works like a champ because the user can only scroll so fast with the mouse wheel vs. the scroll bar when a user can actually scroll to the bottom instantly. At that point my pagination function can’t keep up and I lose the UI for a bit until it catches up.

I will look into the memory DB instead of my 2D array. Thank you again!

[quote=109840:@Norman Palardy]To be honest I’d stuff all this in a db (just in memory even)
Then use something like Kems data on demand listbox or einhugurs data grid to page it
Putting millions of rows IN the listbox will be a memory hog and it will be slower than paging it[/quote]
FWIW after the long load time of 4 million rows either by lazy load or full load … The listbox scrolling is 100% smooth.