speed up listbox refresh

Could you elaborate on this?

@Markus Winter:

In SQL you can define functions for a database which you can use in SQL select statements. I define a function “mailboxname” and can use it like a Xojo function “select mailboxname(mailboxpath) from mailbox”.

In Valentina you can do fields with methods. The syntax for the method definition is similar to the function. The benefit is that the result can be indexed. With this field I then do “select mailboxname_fromPath from mailbox”. This feature was relatively new for me. The function is more generic as you have to hardcode the field you want to use in the method. But this is totally fine here.

Listbox: AddRow vs InsertRow

InsertRow seems a bit faster than AddRow, but only when the call is:

LB.InsertRow (LB.ListCount,"")

Using 0 (instead of LB.ListCount) double the execution time.

Nota: I do not checked AddFolder / InserFolder.

[code] Dim Loop_Idx As Integer
Dim Ticks_Start As Integer
Dim Ticks_End As Integer

Ticks_Start = Ticks

For Loop_Idx = 1 To 100000
// LB.AddRow “” // 6 Ticks for 10000 // 54 Ticks for 100000
// LB.InsertRow (0,"") // 6 Ticks for 10000 // 107 Ticks for 100000
LB.InsertRow (LB.ListCount,"") // 6 Ticks for 10000 // 52 Ticks for 100000

If UserCancelled Then Exit // The goal is to check who’s faster, not how faster the loop is

Next

Ticks_End = Ticks

LB.DeleteAllRows

LB.AddRow "Tick Start: " + Str(Ticks_Start)
LB.AddRow "Tick End: " + Str(Ticks_End)
LB.AddRow "Tick Ellapsed: " + Str(Ticks_End - Ticks_Start)[/code]

Edit: environment
Internet ON
FireFox running,
Xojo 2015r1 running in the IDE
Safari was fired and quit some times ago in this session.

MacBook Pro 13", El Capitan (last)
(Screen: 3360 x 2100)

[quote=328349:@Dave S]Is the best way to reduce the percieved load time of a list box to

  • set VISIBLE=false
  • load the data
  • set VISIBLE=true

and when you do LB.INVALIDATECELL(-1,-1)
does that attempt to refresh ALL the cells, or just all the VISIBLE one?[/quote]

Converting code from Vb6 to xojo i was suprised when i change the flexgrid control (vb6) to ListBox, the same file (18Kb) takes an eternity to populate the listbox, unlike under vb6 (takes less the one second).
I have followed your three recommandations, with out result !
I use a Chilkat.csv plugin to read and load data, the code is like this :

  //Stars.csv file  looks almost like this , 600 lines :
  //2.971, -40.30, 3.0, Acamar
  //1.629, -57.24, 0.6, Achernar
  //16.091,-19.81,2.6, Acrab
  //12.443,-63.10,1.0, Acrux
  //8.975,  11.86, 4.3,  Acubens
  //10.278, 23.42,3.7,  Adhafera
  //6.977,  -28.97,1.5, Adhara
  //5.033, 43.82,3.0, Al Anz
  //11.845, 1.76, 3.6, Alaraph
  //19.513, 27.97, 3.1, Albiero
  //12.140,-24.73,4.1, Alchita
  //3.791,24.11,2.9, Alcyone
  // ...  ....
  
  
  Dim csv As New Chilkat.Csv
  
  //  Prior to loading the CSV file, indicate that the 1st row
  //  should be treated as column names:
  csv.HasColumnNames = True
  
  //  Load the CSV records from the file:
  Dim success As Boolean
  success = csv.LoadFile("C:\\Stars.csv")
  If (success <> True) Then
    System.DebugLog(csv.LastErrorText)
    Return
  End If
  
  
  Dim row As Int32
  Dim n As Int32
  Dim strStar as string
  
  
  n = csv.NumRows
  
  For row = 0 To n - 1
    
    
    Dim RA ,DD, MagV As Double
    
    //Extract data to pop the LB.
    RA= val(csv.GetCell(row,0))
    DD = val(csv.GetCell(row,1))
    MagV =val(csv.GetCell(row,2))
    StrStar =csv.GetCell(row,3)
    
    LB.AddRow Format(row, "00" )
    
    //Récupére l'index de cette nouvelle rangée
    //Dim theRow As Integer = LB.LastIndex
    
    
    LB.Cell( row, 1 ) = format(RA,"#.###")
    LB.Cell(row, 2 ) = format(DD,"-#.###")
    LB.Cell( row, 3 ) =format(MagV,"-#.#")
    LB.Cell( row, 4 ) = strStar
    
    
    //System.DebugLog     str(row) +  "    "  + RA.ToText  +  "      " +  DD.ToText +  "    "   +format(MagV,"-#. #") + "      " + strstar
    
    
  Next
  
  

[quote=328830:@Neil Burkholder]I just tried this and it didn’t make any difference. I’ll summarize my (very surprising) results below.

  • 1,309 seconds with scrollbar and listbox visible
  • 119 seconds with listbox.visible = false and listbox ScrollBarVertical = true
  • 35 seconds with listbox.ScrollBarVertical = false and listbox.visible = true
  • 26 seconds with listbox.ScrollBarVertical = false and listbox.visible = false

In summary hiding the virtical scrollbar is much more important than hiding the listbox.[/quote]

Please put list box in a local variable to speed it up:

Dim LB as Listbox = self.LB

Good practice for lot’s of objects is keeping a reference rather then letting the compiler figure that out each time, over and over again.

[quote=483630:@Christian Schmitz]Please put list box in a local variable to speed it up:

Dim LB as Listbox = self.LB

I tried it : Dim LB as Listbox = self.LB , no change still slow , i reduce the csv file to 4Kb , “77 lines”, the respons time is 2 sec !

The compiler does its thing only once - at compile time.

I’d be interested in knowing how much of a difference referring to a local variable as opposed to a “window scope” variable would actually make, I suspect very little. Pity I’m too lazy to test.

Try changing this

[code] LB.AddRow Format(row, “00” )

//Rcupre l'index de cette nouvelle range
//Dim theRow As Integer = LB.LastIndex


LB.Cell( row, 1 ) = format(RA,"#.###")
LB.Cell(row, 2 ) = format(DD,"-#.###")
LB.Cell( row, 3 ) =format(MagV,"-#.#")
LB.Cell( row, 4 ) = strStar[/code]

To this

[code] LB.AddRow Format(row, “00” ), format(RA,"#.###"), format(DD,"-#.###"), format(MagV,"-#.#"), strStar

[/code]

Is it faster?

EDIT: And actually the bottleneck might be the CSV parser, not the listbox. Did you try measuring times to read CSV vs time to populate listbox ?

You need to find what is causing the slow down by analysing what is going on. Adding 600 lines to a listbox is trivial no matter what formatting you’re doing on each line or that you’re not using a local reference to the listbox.

You need to investigate what is happening, it could be any of the following:

  1. Slow plugin reading from the CSV with GetCell (I’d be surprised) so comment these lines and and replace them with hard coded values to see if you get any change in speed.
  2. Events/code firing that you are unaware of when you are updating the listbox, to help see this use Project>Profile Code and see if you have a call taking up an abnormal amount of time.
  3. Further to 2) Comment out your addorw and LB.Cell changes and see if that speeds things up.
  4. A background thread or timer that is taking time away from this loop.
  5. Some odd way you have your UI set up

[quote=483637:@Jeremie Leroy]Try changing this

[code] LB.AddRow Format(row, “00” )

//Récupére l'index de cette nouvelle rangée
//Dim theRow As Integer = LB.LastIndex


LB.Cell( row, 1 ) = format(RA,"#.###")
LB.Cell(row, 2 ) = format(DD,"-#.###")
LB.Cell( row, 3 ) =format(MagV,"-#.#")
LB.Cell( row, 4 ) = strStar[/code]

To this

[code] LB.AddRow Format(row, “00” ), format(RA,"#.###"), format(DD,"-#.###"), format(MagV,"-#.#"), strStar

[/code]

Is it faster?

EDIT: And actually the bottleneck might be the CSV parser, not the listbox. Did you try measuring times to read CSV vs time to populate listbox ?[/quote]

Jeremie, it’s more slower 3 sec than 2 sec !

[quote=483641:@]You need to find what is causing the slow down by analysing what is going on. Adding 600 lines to a listbox is trivial no matter what formatting you’re doing on each line or that you’re not using a local reference to the listbox.

You need to investigate what is happening, it could be any of the following:

  1. Slow plugin reading from the CSV with GetCell (I’d be surprised) so comment these lines and and replace them with hard coded values to see if you get any change in speed.
  2. Events/code firing that you are unaware of when you are updating the listbox, to help see this use Project>Profile Code and see if you have a call taking up an abnormal amount of time.
  3. Further to 2) Comment out your addorw and LB.Cell changes and see if that speeds things up.
  4. A background thread or timer that is taking time away from this loop.
  5. Some odd way you have your UI set up[/quote]

system.debulog print output values almost instantaneous .

Ok, so its sounds like a display issue. Did you try any of the other suggestions? Do you have timers, thread, overlapping controls, code in other events on the listbox?

What if you extract just the code you posted above, place it into a new test project and see if you have the same problem?

You need to narrow it down by trial and error.

[quote=483641:@]You need to find what is causing the slow down by analysing what is going on. Adding 600 lines to a listbox is trivial no matter what formatting you’re doing on each line or that you’re not using a local reference to the listbox.

You need to investigate what is happening, it could be any of the following:

  1. Slow plugin reading from the CSV with GetCell (I’d be surprised) so comment these lines and and replace them with hard coded values to see if you get any change in speed.
  2. Events/code firing that you are unaware of when you are updating the listbox, to help see this use Project>Profile Code and see if you have a call taking up an abnormal amount of time.
  3. Further to 2) Comment out your addorw and LB.Cell changes and see if that speeds things up.
  4. A background thread or timer that is taking time away from this loop.
  5. Some odd way you have your UI set up[/quote]

This is a Project>profil log for the real code with all the processing between data until results.

What is your CellBackgroundPaint event doing for 7 seconds?
Is it a short piece of code, can you post it here?

[quote=483691:@]What is your CellBackgroundPaint event doing for 7 seconds?
Is it a short piece of code, can you post it here?[/quote]

  Dim x,y as integer
  For x = 0 to (LB.ListCount-1)
    for y = 0 to (LB.ColumnCount-1)
      LB.CellBorderRight(x,y) =LB.BorderThinSolid
      LB.CellBorderLeft(x,y)= LB.BorderThinSolid
      LB.CellBorderTop(x,y)= LB.BorderThinsolid
      LB.CellBorderBottom(x,y)= LB.BorderThinsolid
    next
  next

oh geez that iterates over every cell in the LB on every cell paint
you dont need to do that
just do the one cell you’ve been asked to paint something like

LB.CellBorderRight(row,col) =LB.BorderThinSolid
LB.CellBorderLeft(row,col)= LB.BorderThinSolid
LB.CellBorderTop(row,col)= LB.BorderThinsolid
LB.CellBorderBottom(row,col)= LB.BorderThinsolid

Yeah don’t alter cell borders in a paint events as that CAN trigger another paint and cause recursive paints. Alter those when you set up the data only not every time the cell is painted.

EDIT: will to can, for clarity

even better advice - do like julian says and set the borders once - not every time