 |
AutoHotkey Community Let's help each other out
|
| View previous topic :: View next topic |
| Author |
Message |
Toony Tom Guest
|
Posted: Sat Dec 12, 2009 12:30 pm Post subject: Faster way to add rows to a Listview or an alternative? |
|
|
I'm attempting to build a program to save a list of files on all my dvds and have that list searchable. My problem is that loading more than 30,000 rows into a listview control takes a bit of time. Searching this many rows with a "find as you type" routine becomes really clumsy as well.
Now 30,000 may seem like too much, but I can load winamp, and in less than 10 seconds it's listview is populated with about 17,000 tracks."Everything" is also lightning quick with searching and scanning the hard drive: http://www.voidtools.com/ It actually inspired me to try and code my disc searcher.
Just to give an idea of the time involved, here's a quick simple example:
| Code: | Gui,Font,Bold
Gui, Add, Text,x0 y5 w200 h20 vtext,
Gui,Font,
Gui, Add, ListView, x0 y+ h300 w300 +grid +0x100 +0x40 ,Name|Size|Path|
Gui,Show
Loop,3
LV_ModifyCol(a_index,"AutoHdr")
Loop,50000
{
types=avi,mp3,txt,psd
index:=a_index
Loop,Parse,types,CSV
{
LV_Add("",index "." a_loopfield,"0 kb",a_workingdir "\temp\")
}
GuiControl,,text,Loading....%index%
}
Loop,3
LV_ModifyCol(a_index,"AutoHdr")
GuiControl,,text,Done! with %index% rows
return
|
Maybe using a listview in the first place to display this many results is a bad idea, but it looked good because it's "the" control to use when displaying files. If anyone has a better solution I'm all ears  |
|
| Back to top |
|
 |
UncleScrooge
Joined: 14 Apr 2009 Posts: 75 Location: Italy
|
Posted: Sat Dec 12, 2009 1:43 pm Post subject: |
|
|
maybe not faster but neater imo
| Code: | Gui,Font,Bold
Gui, Add, Text,x0 y5 w200 h20 vtext,
Gui,Font,
Gui, Add, ListView, % "x0 y+ h". (A_ScreenHeight // 2) . " w" (A_ScreenWidth // 1.5) "+grid +0x100 +0x40", Name|Extension|Size (KB)|Full Path
Gui, Add, Button, % "xp yp+" . (A_ScreenHeight // 2) . " gChangeRoot", Change Root
Gui,Show, AutoSize
LV_ModifyCol(1, (A_ScreenWidth // 1.5) // 5)
LV_ModifyCol(2, (A_ScreenWidth // 1.5) // 14)
LV_ModifyCol(3, (A_ScreenWidth // 1.5) // 14)
FilesPattern := ".mpg,.mp3,.wav" ; you name it...
BeginFrom := "c:\" ; you choose where to begin
BuildLV()
Return
ChangeRoot:
FileSelectFolder, BeginFrom, % "*" . BeginFrom
If ErrorLevel
Return
BeginFrom .= "\"
LV_Delete()
BuildLV()
Return
GuiClose:
ExitApp
BuildLV()
{
global
Loop Parse, FilesPattern, `,
{
If (A_LoopField = "")
Continue
Loop % BeginFrom . "*" . A_LoopField, 0, 1
{
LV_Add("",A_LoopFileName, A_LoopFileExt, A_LoopFileSizeKB, A_LoopFileLongPath)
GuiControl,,text, % "Loading.... " . LV_GetCount()
}
}
GuiControl,,text, % "Done! with " . LV_GetCount() . " rows."
Return
} |
no counters, but let the Loop scan for wanted files.
The above example actually scans the whole C: HDD, you might want to narrow that range...
EDIT: I've added a Button by means of which you can select the range of your media files search. Needless to say: change the FilesPattern variable contents to scan other type of files (or you could add another control to let the user (yourself...?) make the choice. _________________ Intel Centrino @ 2.8GHz
4 GB RAM
WIN XP SP3
Last edited by UncleScrooge on Sat Dec 12, 2009 5:07 pm; edited 2 times in total |
|
| Back to top |
|
 |
hd0202
Joined: 13 Aug 2006 Posts: 265 Location: Germany
|
Posted: Sat Dec 12, 2009 4:16 pm Post subject: Re: Faster way to add rows to a Listview or an alternative? |
|
|
Add | Code: | | GuiControl, -Redraw, ListView | before your loop and | Code: | | GuiControl, +Redraw, ListView | after your loop
Hubert |
|
| Back to top |
|
 |
UncleScrooge
Joined: 14 Apr 2009 Posts: 75 Location: Italy
|
Posted: Sat Dec 12, 2009 4:59 pm Post subject: Re: Faster way to add rows to a Listview or an alternative? |
|
|
| hd0202 wrote: | Add | Code: | | GuiControl, -Redraw, ListView | before your loop and | Code: | | GuiControl, +Redraw, ListView | after your loop
Hubert |
not quite so...
moreover you loose the "feeling" of the filling up List view: staring at a blank ListView for 64 secs is worth looking at the partial filling already done (where you can scroll, select, etc.) for 67 secs, that is 3 secs over a minute (5% improvement in performace)?
| Code: | ---------------------------
temptest.ahk
---------------------------
66875 mSecs. With +/- Redraw option OFF Over 23428 red Items.
---------------------------
OK
---------------------------
---------------------------
temptest.ahk
---------------------------
64265 mSecs. With +/- Redraw option ON Over 23428 red Items.
---------------------------
OK |
test it yourself (you should include a substantial number of file though, add some more extensions in the"FilesPattern" variable...):
| Code: | ChkBoxString := "+/- Listview Redraw option is "
Gui,Font,Bold
Gui, Add, Text,x0 y5 w200 h20 vtext,
Gui,Font,
Gui, Add, ListView, % "x0 y+ h". (A_ScreenHeight // 2) . " w" (A_ScreenWidth // 1.5) "+grid +0x100 +0x40 vMyListView", Name|Extension|Size (KB)|Full Path
Gui, Add, Button, % "xp yp+" . (A_ScreenHeight // 2) . " gChangeRoot", Change Root
Gui, add, Checkbox, xp+200 yp vMyCheckBox gMyCheckBox, %ChkBoxString%ON
Gui,Show, AutoSize
LV_ModifyCol(1, (A_ScreenWidth // 1.5) // 5)
LV_ModifyCol(2, (A_ScreenWidth // 1.5) // 14)
LV_ModifyCol(3, (A_ScreenWidth // 1.5) // 14)
FilesPattern := ".mpg,.mp3,.wav" ; you name it...
BeginFrom := "c:\" ; you choose where to begin
BuildLV()
Return
ChangeRoot:
FileSelectFolder, BeginFrom, % "*" . BeginFrom
If ErrorLevel
Return
BeginFrom .= "\"
LV_Delete()
BuildLV()
Return
GuiClose:
ExitApp
BuildLV()
{
global
start := A_TickCount
If MyCheckBox
GuiControl, -Redraw, MyListView
Loop Parse, FilesPattern, `,
{
If (A_LoopField = "")
Continue
Loop % BeginFrom . "*" . A_LoopField, 0, 1
{
LV_Add("",A_LoopFileName, A_LoopFileExt, A_LoopFileSizeKB, A_LoopFileLongPath)
GuiControl,,text, % "Loading.... " . LV_GetCount()
}
}
If MyCheckBox
GuiControl, +Redraw, MyListView
GuiControl,,text, % "Done! with " . LV_GetCount() . " rows."
MyCheckBox ? msg := " mSecs. With +/- Redraw option ON" : msg := " mSecs. With +/- Redraw option OFF"
MsgBox % A_TickCount - start . msg . " Over " . LV_GetCount() . " red Items."
Return
}
MyCheckBox:
Gui, Submit, NoHide
GuiControl,, MyCheckBox, % MyCheckBox ? ChkBoxString . "ON" : ChkBoxString . "OFF"
Return |
_________________ Intel Centrino @ 2.8GHz
4 GB RAM
WIN XP SP3 |
|
| Back to top |
|
 |
Toony Tom Guest
|
Posted: Sun Dec 13, 2009 2:20 am Post subject: |
|
|
That's a good point actually UncleScrooge. Don't want to bore the user by making him stare at a blank control I remembered RaGrid today and began playing with it.
Loading the RaGrid control up with 50,000 rows took:
33,828ms or about 34 seconds!!!!
by contrast loading the listview control took:
411,563ms or about 7 minutes!!!!
RaGrid:
http://www.autohotkey.com/forum/topic19253.html
Here's the modified example code I used for RaGrid:
| Code: | #SingleInstance, force
start := A_TickCount
w := 1000, h := 500, header := 30
Gui, +LastFound +Resize
hwnd := WinExist()
Gui, Add, Button,x0 gOnBtn, Insert
Gui, Add, Button,x+0 yp gOnBtn, Delete
Gui, Add, Button,x+0 yp gOnBtn, Move Up
Gui, Add, Button,x+0 yp gOnBtn, Move Down
Gui, Add, Button,x+20 yp gOnBtn, Colorize Row
Gui, Add, Button,x+0 yp gOnBtn, Set Colors
Gui, Add, Button,x+20 yp gOnBtn, Read Cell
Gui, Add, Button,x+5 yp gOnBtn, Convert Cell
Gui, Add, Button,x+5 yp gOnBtn, Sort Column
Gui, Add, Button,x+40 yp gOnBtn, Reload
Gui, Add, StatusBar, ,Loading data
Gui, Show, h%h% w%w%
hIL := ImageList_Create(16, 16, 0x21, 255, 10)
Loop 255
ImageList_AddIcon(hIL, LoadIcon("shell32.dll", A_Index, 16))
hGrd := RG_Add(hwnd, 0, header, w, h-header-30, "GRIDFRAME VGRIDLINES NOSEL", "OnRa" ), Attach(hGrd, "w h")
;RG_SetFont(hGrd, "s8, Courier New")
RG_SetHdrHeight(hGrd, 20), RG_SetRowHeight(hGrd, 26)
loop, 1
{
RG_AddColumn(hGrd, "txt=EditText", "w=100", "hdral=1", "txtal=1", "type=EditText")
RG_AddColumn(hGrd, "txt=EditLong", "w=100", "hdral=1", "txtal=1", "type=EditLong", "format=# ### ####")
RG_AddColumn(hGrd, "txt=Combo", "w=90", "hdral=1", "txtal=1", "type=ComboBox", "items=combo 1|combo 2|combo 3|combo 4|combo 5|combo 6|combo 7|combo 8|combo 9|combo 10|combo 11|combo 12")
RG_AddColumn(hGrd, "txt=Check", "w=70", "hdral=1", "txtal=1", "type=CheckBox")
RG_AddColumn(hGrd, "txt=Button", "w=100", "hdral=1", "txtal=1", "type=Button")
RG_AddColumn(hGrd, "txt=EButton", "w=100", "hdral=1", "txtal=1", "type=EditButton")
RG_AddColumn(hGrd, "txt=Image", "w=100", "hdral=1", "txtal=1", "type=Image", "il=" hIL)
RG_AddColumn(hGrd, "txt=Hotkey", "w=100", "hdral=1", "txtal=1", "type=Hotkey")
RG_AddColumn(hGrd, "txt=Date", "w=100", "hdral=1", "txtal=1", "type=Date", "format=yy'-'MM'-'dd")
RG_AddColumn(hGrd, "txt=Time", "w=100", "hdral=1", "txtal=1", "type=Time", "format=HH':'mm")
RG_AddColumn(hGrd, "txt=User", "w=100", "hdral=1", "txtal=1", "type=User", "data=1234")
}
loop, 50000
RG_AddRow(hGrd, 0, "Text" A_Index ,A_Index, mod(A_Index, 12), mod(A_Index, 2), "btn" A_Index, "",mod(A_Index, 255))
;, RG_AddRow(hGrd, 0 " " 10, "Text" A_Index ,A_Index, mod(A_Index, 12), mod(A_Index, 2), "btn" A_Index, "", mod(A_Index, 255))
SB_SetText("Loading finished`n`nRows " RG_GetRowCount(hGrd) " Cols " RG_GetColCount(hGrd))
MsgBox % A_TickCount - start "ms for 50,000 items"
return
OnBtn:
if A_GuiControl = Insert
RG_AddRow(hGrd, RG_GetCurrentRow(hGrd))
#Include RaGrid.ahk
#include inc\Attach.ahk
#include inc\Il.ahk |
Now, I just hope I can learn to use RaGrid correctly  |
|
| Back to top |
|
 |
entropic
Joined: 21 Dec 2008 Posts: 181
|
Posted: Sun Dec 13, 2009 3:16 am Post subject: |
|
|
This loads a listview with 50k rows in about 1.5 seconds on my machine and 500,000 rows in 14 seconds.
| Code: |
SetBatchLines, -1
Gui, Font, Bold
Gui, Add , Text ,x0 y5 h020 w200 vtext,
Gui, Font,
Gui, Add , ListView, x0 y+ h300 w300 +grid +0x100 +0x40 vMyListView Count50000 ,Name|Size|Path|
GuiControl, -Redraw, MyListView
Gui, Show
Loop,3
LV_ModifyCol(a_index,"AutoHdr")
StartTime := A_TickCount
Loop, 50000
{
LV_Add("", A_Index,"0 kb",a_workingdir "\temp\")
}
GuiControl, +Redraw, MyListView
Loop,3
LV_ModifyCol(a_index,"AutoHdr")
Msgbox, % "Total Time: " A_TickCount - StartTime . "ms"
SetBatchLines, 10ms
return
|
Edit:
Everything by Void Tools is so quick because it builds the file list from the Master File Table, for changes it uses the USN Journal. I think it probably also loads the ListView as you scroll rather than loading everything at once, as you scroll you can see it loading the icons.
Last edited by entropic on Sun Dec 13, 2009 3:39 am; edited 2 times in total |
|
| Back to top |
|
 |
Toony Tom Guest
|
Posted: Sun Dec 13, 2009 3:23 am Post subject: |
|
|
It loads in 17 seconds for me. I'm curious what kind of setup you have. I'm running windows xp pro SP3 (32 bit) on an AMD quad core 2.4ghz with 4gb of ram. |
|
| Back to top |
|
 |
entropic
Joined: 21 Dec 2008 Posts: 181
|
Posted: Sun Dec 13, 2009 3:32 am Post subject: |
|
|
| I'm on a dual core Pentium 4 3.0ghz with 3gb ram, WinXp Sp3 (32bit). I'm not sure why mine is faster. |
|
| Back to top |
|
 |
Toony Tom Guest
|
Posted: Sun Dec 13, 2009 7:14 am Post subject: |
|
|
Well now, I do believe I figured out part of the problem. I had a lot of applications running, mainly my browser with it's many cpu gobbling tabs and ram hogging pages. I killed everything and found that loading 50 thousand rows took 2 seconds compared with 17 from before. Also 500 thousand rows took 22 seconds compared with 3 to 4 minutes with your code before. Live and learn and viva la listview! |
|
| Back to top |
|
 |
MakeMyPCBetter
Joined: 19 Dec 2008 Posts: 27
|
Posted: Wed Jan 27, 2010 9:54 pm Post subject: Speed up Load times in List View |
|
|
This Sped my process up alot
I used to use a Parsing loop.
| Code: | Loop, read, %Data_Base_File_Name%
{
DataBase_Record_Count = %A_Index%
;Add Feilds into List View
StringSplit, Record_Array, A_LoopReadLine, `,
LV_Add("",Record_Array1,Record_Array2,Record_Array3,Record_Array4)
} |
|
|
| Back to top |
|
 |
|
|
You can post new topics in this forum You can reply to topics in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|