Filling a big number of items in a ComboBoxGadget()

Share your advanced PureBasic knowledge/code with the community.
User avatar
Flype
Addict
Addict
Posts: 1542
Joined: Tue Jul 22, 2003 5:02 pm
Location: In a long distant galaxy

Filling a big number of items in a ComboBoxGadget()

Post by Flype »

Code updated For 5.20+

Filling more than 10000 items in a combobox take too much time for you ?
On my computer it take 3645ms to fill 50000 items and with this API function it take only 310ms. :P
Source code [PB4.0]

Code: Select all

#nItem = 50000

Enumeration
  #gCombo
  #gText1
  #gText2
  #gDo1
  #gDo2
EndEnumeration

Procedure Do1()
  SetGadgetText(#gText1,"Processing...")
  ClearGadgetItems(#gCombo)
  time = ElapsedMilliseconds()
  For i=0 To #nItem
    AddGadgetItem(#gCombo,i,RSet(Str(i),8,"0")+":$"+RSet(Hex(i),8,"0"))
  Next
  SetGadgetText(#gText1,Str(ElapsedMilliseconds()-time)+" ms")
  SetGadgetState(#gCombo,0)
EndProcedure

Procedure Do2()
  SetGadgetText(#gText2,"Processing...")
  ClearGadgetItems(#gCombo)
  time = ElapsedMilliseconds()
  ;############################################################
  BufferSize = #nItem * 20
  SendMessage_(GadgetID(#gCombo),#CB_INITSTORAGE,0,BufferSize)
  ;############################################################
  For i=0 To #nItem
    AddGadgetItem(#gCombo,i,RSet(Str(i),8,"0")+":$"+RSet(Hex(i),8,"0"))
  Next
  SetGadgetText(#gText2,Str(ElapsedMilliseconds()-time)+" ms")
  SetGadgetState(#gCombo,0)
EndProcedure

If OpenWindow(0,150,150,200,85,"Number of items : "+Str(#nitem),#PB_Window_SystemMenu)
  ;       If CreateGadgetList(WindowID(0))
  ComboBoxGadget(#gCombo,5,5,190,300)
  TextGadget(#gText1,5,30,90,22,"",#PB_Text_Border)
  TextGadget(#gText2,105,30,90,22,"",#PB_Text_Border)
  ButtonGadget(#gDo1,5,58,90,22,"Test 1")
  ButtonGadget(#gDo2,105,58,90,22,"Test 2")
  Repeat
    Select WaitWindowEvent()
      Case #PB_Event_CloseWindow: Break
      Case #PB_Event_Gadget
        Select EventGadget()
          Case #gDo1: Do1()
          Case #gDo2: Do2()
        EndSelect
    EndSelect
  ForEver
  ;       EndIf
EndIf
No programming language is perfect. There is not even a single best language.
There are only languages well suited or perhaps poorly suited for particular purposes. Herbert Mayer
Polo
Addict
Addict
Posts: 2422
Joined: Tue May 06, 2003 5:07 pm
Location: UK

Post by Polo »

first test : 3495ms
second test : 3194ms
Not that much difference (P4 1.5ghtz)
Nico
Enthusiast
Enthusiast
Posts: 274
Joined: Sun Jan 11, 2004 11:34 am
Location: France

Post by Nico »

Here are my results:

test1: 5989ms
test2: 4677ms

The difference is not enormous for me !!!

Athon 1500Mhz
User avatar
Flype
Addict
Addict
Posts: 1542
Joined: Tue Jul 22, 2003 5:02 pm
Location: In a long distant galaxy

Post by Flype »

AMD Athlon 1.3Ghz on WinXP, 512mb, and it works well for me.
It should work with 95/NT/XP...

can you try to replace these 2 lines ? :

Code: Select all

  ;############################################################
  SendMessage_(GadgetID(#gCombo),#CB_INITSTORAGE,#nItem,#nItem*20)
  ;############################################################
No programming language is perfect. There is not even a single best language.
There are only languages well suited or perhaps poorly suited for particular purposes. Herbert Mayer
Polo
Addict
Addict
Posts: 2422
Joined: Tue May 06, 2003 5:07 pm
Location: UK

Post by Polo »

doesn't change :(
User avatar
Flype
Addict
Addict
Posts: 1542
Joined: Tue Jul 22, 2003 5:02 pm
Location: In a long distant galaxy

Post by Flype »

What's your OS ?
this one : 31255ms / 511ms with 100000 items.

Code: Select all

#nItem = 100000

Enumeration 
  #gCombo
  #gText1
  #gText2
  #gDo1
  #gDo2
EndEnumeration

Procedure Do1() 
  SetGadgetText(#gText1,"Processing...") 
  ClearGadgetItemList(#gCombo) 
  time = ElapsedMilliseconds() 
  For i=0 To #nItem
    AddGadgetItem(#gCombo,i,"ABCDEFGHIJKLMNOPQRSTUVWXYZ") 
  Next
  SetGadgetText(#gText1,Str(ElapsedMilliseconds()-time)+" ms") 
  SetGadgetState(#gCombo,0) 
EndProcedure 
    
Procedure Do2() 
  SetGadgetText(#gText2,"Processing...") 
  ClearGadgetItemList(#gCombo) 
  time = ElapsedMilliseconds()
  ;############################################################
  SendMessage_(GadgetID(#gCombo),#CB_INITSTORAGE,#nItem,#nItem*27)
  ;############################################################
  For i=0 To #nItem
    AddGadgetItem(#gCombo,i,"ABCDEFGHIJKLMNOPQRSTUVWXYZ") 
  Next
  SetGadgetText(#gText2,Str(ElapsedMilliseconds()-time)+" ms") 
  SetGadgetState(#gCombo,0) 
EndProcedure 

If OpenWindow(0,150,150,200,85,#PB_Window_SystemMenu,"Number of items : "+Str(#nitem))
  If CreateGadgetList(WindowID(0)) 
    ComboBoxGadget(#gCombo,5,5,190,300) 
    TextGadget(#gText1,5,30,90,22,"",#PB_Text_Border)
    TextGadget(#gText2,105,30,90,22,"",#PB_Text_Border)
    ButtonGadget(#gDo1,5,58,90,22,"Test 1") 
    ButtonGadget(#gDo2,105,58,90,22,"Test 2") 
    Repeat 
      Select WaitWindowEvent() 
        Case #PB_Event_CloseWindow: Break
        Case #PB_Event_Gadget
          Select EventGadget() 
          Case #gDo1: Do1()
          Case #gDo2: Do2()
          EndSelect 
      EndSelect 
    ForEver
  EndIf
EndIf
No programming language is perfect. There is not even a single best language.
There are only languages well suited or perhaps poorly suited for particular purposes. Herbert Mayer
Polo
Addict
Addict
Posts: 2422
Joined: Tue May 06, 2003 5:07 pm
Location: UK

Post by Polo »

I'm on Windows XP Home.
With the new test :
16874ms
13049ms

Strange that it's twice much faster with the test1 in comparison with you, but, a lot slower with the test2 :?
Trond
Always Here
Always Here
Posts: 7446
Joined: Mon Sep 22, 2003 6:45 pm
Location: Norway

Post by Trond »

The one with 5{x} items:
Test 1: 3686 ms
Test 2: 2814 ms

A lot of people here are probably running with the debugger enabled and that messes up the speeds.

By the way, this one blows the doors off Do2(), it executes at times from <511 to 640 ms here (and it also saves some time outside the time measuring commands):

Code: Select all

Procedure Do3() 
  SetGadgetText(#gText2,"Processing...") 
  ClearGadgetItemList(#gCombo) 
  time = ElapsedMilliseconds() 
  SendMessage_(GadgetID(#gCombo),#CB_INITSTORAGE,0,#nItem * 40) 
  For i=0 To #nItem 
    AddGadgetItem(#gCombo,i,RSet(Str(i),8,"0")+":$"+RSet(Hex(i),8,"0")) 
  Next 
  SetGadgetText(#gText2,Str(ElapsedMilliseconds()-time)+" ms") 
  SetGadgetState(#gCombo,0)
EndProcedure 
Polo
Addict
Addict
Posts: 2422
Joined: Tue May 06, 2003 5:07 pm
Location: UK

Post by Polo »

I'm running with debugger disabled, of course....
User avatar
Flype
Addict
Addict
Posts: 1542
Joined: Tue Jul 22, 2003 5:02 pm
Location: In a long distant galaxy

Post by Flype »

it seems that with xp theme enabled (not only in compiler options but also in panel control) it's much slower.
try without...
No programming language is perfect. There is not even a single best language.
There are only languages well suited or perhaps poorly suited for particular purposes. Herbert Mayer
Nico
Enthusiast
Enthusiast
Posts: 274
Joined: Sun Jan 11, 2004 11:34 am
Location: France

Post by Nico »

It's good with this:
SendMessage_(GadgetID(#gCombo),#CB_INITSTORAGE,#nItem,#nItem*27*2)

Window xp is unicode then I think that the problem comes from there!

Window works with the unicode even if we look to her of the ASCII, he takes charge of the conversion in both directions!

Now I have:

1er test: 36162
2eme test: 1652

It's very good now! :D
Dare2
Moderator
Moderator
Posts: 3321
Joined: Sat Dec 27, 2003 3:55 am
Location: Great Southern Land

Post by Dare2 »

@Trond, Nico

Do3 does blow everything away! Neat!
@}--`--,-- A rose by any other name ..
User avatar
netmaestro
PureBasic Bullfrog
PureBasic Bullfrog
Posts: 8451
Joined: Wed Jul 06, 2005 5:42 am
Location: Fort Nelson, BC, Canada

Post by netmaestro »

1375 do1
1149 do2
468 do3

on my machine (see sig.)
Last edited by netmaestro on Sat Feb 25, 2006 7:00 am, edited 3 times in total.
BERESHEIT
MrMat
Enthusiast
Enthusiast
Posts: 762
Joined: Sun Sep 05, 2004 6:27 am
Location: England

Post by MrMat »

Redraws can be turned off whilst the gadget is being populated for a nice speed boost, e.g. stick this around the loop:

Code: Select all

SendMessage_(GadgetID(#gCombo), #WM_SETREDRAW, #False, 0)
; loop goes here
SendMessage_(GadgetID(#gCombo), #WM_SETREDRAW, #True, 0)
InvalidateRect_(GadgetID(#gCombo), 0, #True)
Mat
Trond
Always Here
Always Here
Posts: 7446
Joined: Mon Sep 22, 2003 6:45 pm
Location: Norway

Post by Trond »

MrMat wrote:Redraws can be turned off whilst the gadget is being populated for a nice speed boost, e.g. stick this around the loop:

Code: Select all

SendMessage_(GadgetID(#gCombo), #WM_SETREDRAW, #False, 0)
; loop goes here
SendMessage_(GadgetID(#gCombo), #WM_SETREDRAW, #True, 0)
InvalidateRect_(GadgetID(#gCombo), 0, #True)
I tried with LockWindowUpdate() but it didn't matter.
Post Reply