Zedna Posted April 3, 2008 Share Posted April 3, 2008 (edited) 1) GUICtrlCreateListViewItem() - very quick 2) _GUICtrlListView_AddItem(ControlId) - MUCH slower 3) _GUICtrlListView_AddItem(ControlHwnd) - even MUCH more slower I think 1) and 2) should have similar time consume amount and not such big differences. I saw it's sources. Times in parenthesis are from another computer. All times are avg from several runs (all on 3.2.10 version) expandcollapse popup#include <GUIConstants.au3> #include <GUIListView.au3> $gui = GUICreate("listview items", 320, 250, 100, 200) $listview = GUICtrlCreateListView("col1 |col2|col3 ", 10, 10, 200, 150);,$LVS_SORTDESCENDING) $hListView = ControlGetHandle($gui, '', $listview) $button1 = GUICtrlCreateButton("Create std", 15, 170, 70, 20) $button2 = GUICtrlCreateButton("Create UDF", 125, 170, 70, 20) $button3 = GUICtrlCreateButton("Delete UDF", 200, 170, 70, 20) $input1 = GUICtrlCreateInput("", 20, 200, 150) GUISetState() Do $msg = GUIGetMsg() Select Case $msg = $button1 $start = TimerInit() For $i = 1 To 4000 GUICtrlCreateListViewItem("item1|col2|col3", $listview) Next GUICtrlSetData($input1, 'Time: ' & TimerDiff($start)) ; 440 ms (650) Case $msg = $button2 $start = TimerInit() For $i = 1 To 4000 _GUICtrlListView_AddItem($ListView, "item1|col2|col3") ;~ _GUICtrlListView_AddItem($hListView, "item1|col2|col3") Next GUICtrlSetData($input1, 'Time: ' & TimerDiff($start)) ; 1250 ms with $ListView (2650) ; 1980 ms with $hListView (12000) Case $msg = $button3 _GUICtrlListView_DeleteAllItems($hListView) EndSelect Until $msg = $GUI_EVENT_CLOSE Is this only _GUICtrlListView_AddItem() speed limitation or some bug/not optimized code in UDF? Edited April 3, 2008 by Zedna pixelsearch 1 Resources UDF ResourcesEx UDF AutoIt Forum Search Link to comment Share on other sites More sharing options...
GaryFrost Posted April 3, 2008 Share Posted April 3, 2008 Look at _GUICtrlListView_InsertItem, if you can see a way to optimize i'm all for it. SciTE for AutoItDirections for Submitting Standard UDFs Don't argue with an idiot; people watching may not be able to tell the difference. Link to comment Share on other sites More sharing options...
martin Posted April 3, 2008 Share Posted April 3, 2008 1) GUICtrlCreateListViewItem() - very quick 2) _GUICtrlListView_AddItem(ControlId) - MUCH slower 3) _GUICtrlListView_AddItem(ControlHwnd) - even MUCH more slower I think 1) and 2) should have similar time consume amount and not such big differences. I saw it's sources. Times in parenthesis are from another computer. All times are avg from several runs (all on 3.2.10 version) expandcollapse popup#include <GUIConstants.au3> #include <GUIListView.au3> $gui = GUICreate("listview items", 320, 250, 100, 200) $listview = GUICtrlCreateListView("col1 |col2|col3 ", 10, 10, 200, 150);,$LVS_SORTDESCENDING) $hListView = ControlGetHandle($gui, '', $listview) $button1 = GUICtrlCreateButton("Create std", 15, 170, 70, 20) $button2 = GUICtrlCreateButton("Create UDF", 125, 170, 70, 20) $button3 = GUICtrlCreateButton("Delete UDF", 200, 170, 70, 20) $input1 = GUICtrlCreateInput("", 20, 200, 150) GUISetState() Do $msg = GUIGetMsg() Select Case $msg = $button1 $start = TimerInit() For $i = 1 To 4000 GUICtrlCreateListViewItem("item1|col2|col3", $listview) Next GUICtrlSetData($input1, 'Time: ' & TimerDiff($start)) ; 440 ms (650) Case $msg = $button2 $start = TimerInit() For $i = 1 To 4000 _GUICtrlListView_AddItem($ListView, "item1|col2|col3") ;~ _GUICtrlListView_AddItem($hListView, "item1|col2|col3") Next GUICtrlSetData($input1, 'Time: ' & TimerDiff($start)) ; 1250 ms with $ListView (2650) ; 1980 ms with $hListView (12000) Case $msg = $button3 _GUICtrlListView_DeleteAllItems($hListView) EndSelect Until $msg = $GUI_EVENT_CLOSE Is this only _GUICtrlListView_AddItem() speed limitation or some bug/not optimized code in UDF? This is largely a Windows problem IMO. I have had exactly this problem in Delphi with sorting listviews. I think the reason is that windows tries to redraw the listview every time an item is added. If you stop it being redrawn, for example by hiding it, then it is much faster. expandcollapse popup#include <GUIConstants.au3> #include <GUIListView.au3> $gui = GUICreate("listview items", 320, 250, 100, 200) $listview = GUICtrlCreateListView("col1 |col2|col3 ", 10, 10, 200, 150);,$LVS_SORTDESCENDING) $hListView = ControlGetHandle($gui, '', $listview) $button1 = GUICtrlCreateButton("Create std", 15, 170, 70, 20) $button2 = GUICtrlCreateButton("Create UDF", 125, 170, 70, 20) $button3 = GUICtrlCreateButton("Delete UDF", 200, 170, 70, 20) $input1 = GUICtrlCreateInput("", 20, 200, 150) GUISetState() Do $msg = GUIGetMsg() Select Case $msg = $button1 ;GUICtrlSetState($listview,$GUI_HIDE) _SendMessage(ControlGetHandle($gui,"",$listview),$WM_SETREDRAW,0,0) $start = TimerInit() For $i = 1 To 4000 GUICtrlCreateListViewItem("item1|col2|col3", $listview) Next GUICtrlSetData($input1, 'Time: ' & TimerDiff($start)) ;GUICtrlSetState($listview,$GUI_SHOW) _SendMessage(ControlGetHandle($gui,"",$listview),$WM_SETREDRAW,1,0) ; 440 ms (650) Case $msg = $button2 $start = TimerInit() For $i = 1 To 4000 _GUICtrlListView_AddItem($ListView, "item1|col2|col3") ;~ _GUICtrlListView_AddItem($hListView, "item1|col2|col3") Next GUICtrlSetData($input1, 'Time: ' & TimerDiff($start)) ; 1250 ms with $ListView (2650) ; 1980 ms with $hListView (12000) Case $msg = $button3 _GUICtrlListView_DeleteAllItems($hListView) EndSelect Until $msg = $GUI_EVENT_CLOSE (Your PC is about 2 times faster than mine ) Serial port communications UDF Includes functions for binary transmission and reception.printing UDF Useful for graphs, forms, labels, reports etc.Add User Call Tips to SciTE for functions in UDFs not included with AutoIt and for your own scripts.Functions with parameters in OnEvent mode and for Hot Keys One function replaces GuiSetOnEvent, GuiCtrlSetOnEvent and HotKeySet.UDF IsConnected2 for notification of status of connected state of many urls or IPs, without slowing the script. Link to comment Share on other sites More sharing options...
Zedna Posted April 3, 2008 Author Share Posted April 3, 2008 Look at _GUICtrlListView_InsertItem, if you can see a way to optimize i'm all for it.Maybe look into AutoIt sources and compare native AutoIt with UDF because native one is speed winner. I have no access to AutoIt GUI sources. Resources UDF ResourcesEx UDF AutoIt Forum Search Link to comment Share on other sites More sharing options...
GaryFrost Posted April 3, 2008 Share Posted April 3, 2008 _GUICtrlListView_BeginUpdate _GUICtrlListView_EndUpdate SciTE for AutoItDirections for Submitting Standard UDFs Don't argue with an idiot; people watching may not be able to tell the difference. Link to comment Share on other sites More sharing options...
martin Posted April 3, 2008 Share Posted April 3, 2008 _GUICtrlListView_BeginUpdate_GUICtrlListView_EndUpdateOh yes, thanks. Serial port communications UDF Includes functions for binary transmission and reception.printing UDF Useful for graphs, forms, labels, reports etc.Add User Call Tips to SciTE for functions in UDFs not included with AutoIt and for your own scripts.Functions with parameters in OnEvent mode and for Hot Keys One function replaces GuiSetOnEvent, GuiCtrlSetOnEvent and HotKeySet.UDF IsConnected2 for notification of status of connected state of many urls or IPs, without slowing the script. Link to comment Share on other sites More sharing options...
Siao Posted April 3, 2008 Share Posted April 3, 2008 Compiled code is much faster than interpreted code, that's a given. I'm surprised that you are surprised. You can optimize it to perform better in such benchmark, for example, _GUICtrlListView_AddItem() in fact does nothing but call the _GUICtrlListView_InsertItem(), so simply by calling the latter yourself you'd make that 4000 iteration loop a tiny bit faster. Also, if you "saw it's sources", there's quite a few things that need to be done before actual sendmessage takes place, and that's repeated for each iteration - waste of precious time if you intend to add that many items in a row (as basically you only need to repeat 2 actions - setting new text in buffer and sending LVM_INSERTITEM message). You could write custom function moving the For loop inside of it, and that would reduce total time dramatically. But it will be slower still, as it should. Zedna 1 "be smart, drink your wine" Link to comment Share on other sites More sharing options...
Zedna Posted April 3, 2008 Author Share Posted April 3, 2008 This is largely a Windows problem IMO. I have had exactly this problem in Delphi with sorting listviews.I think the reason is that windows tries to redraw the listview every time an item is added. If you stop it being redrawn, for example by hiding it, then it is much faster.You are absolutely right about _SendMessage($hlistview,$WM_SETREDRAW,0,0) stuff, thanks.With this optimization it's faster but relative differences among 1) 2) 3) cases are the same. So question still remains: Why is native GUICtrlCreateListViewItem() so much faster? Resources UDF ResourcesEx UDF AutoIt Forum Search Link to comment Share on other sites More sharing options...
Zedna Posted April 3, 2008 Author Share Posted April 3, 2008 Compiled code is much faster than interpreted code, that's a given.I'm surprised that you are surprised. You can optimize it to perform better in such benchmark, for example, _GUICtrlListView_AddItem() in fact does nothing but call the _GUICtrlListView_InsertItem(), so simply by calling the latter yourself you'd make that 4000 iteration loop a tiny bit faster. Also, if you "saw it's sources", there's quite a few things that need to be done before actual sendmessage takes place, and that's repeated for each iteration - waste of precious time if you intend to add that many items in a row (as basically you only need to repeat 2 actions - setting new text in buffer and sending LVM_INSERTITEM message). You could write custom function moving the For loop inside of it, and that would reduce total time dramatically. But it will be slower still, as it should.Yes Siao you are right.I know used UDFs are general so they have some overhead.But I didn't expect 3times or 4times worse time than native one.So I asked question if there is some "magic" code used inside native GUICtrlCreateListViewItem(). I will definitely try new tests based on your and martin's ideas and I will post results...Thanks for all ideas. Resources UDF ResourcesEx UDF AutoIt Forum Search Link to comment Share on other sites More sharing options...
Zedna Posted April 4, 2008 Author Share Posted April 4, 2008 (edited) Here is optimized version which is even quicker than native one! But I noticed that UDF and also my optimized UDF only adds first column and not all subitems like native one. So I will create also test for all subitems. Note: Times are: without WM_SETREDRAW / with $WM_SETREDRAW = 0 native: 440/310 ms UDF: 1250/1120 ms UDF optimized: 365/240 ms expandcollapse popup#include <GUIConstants.au3> #include <GUIListView.au3> $gui = GUICreate("listview items", 320, 250, 100, 200) $listview = GUICtrlCreateListView("col1 |col2|col3 ", 10, 10, 200, 150);,$LVS_SORTDESCENDING) $hListView = ControlGetHandle($gui, '', $listview) $button1 = GUICtrlCreateButton("Create std", 15, 170, 70, 20) $button2 = GUICtrlCreateButton("Create UDF", 125, 170, 70, 20) $button3 = GUICtrlCreateButton("Delete UDF", 200, 170, 70, 20) $input1 = GUICtrlCreateInput("", 20, 200, 150) GUISetState() Global $pBuffer, $tBuffer, $pItem, $tItem $tItem = DllStructCreate($tagLVITEM) $pItem = DllStructGetPtr($tItem) $tBuffer = DllStructCreate("char Text[2048]") $pBuffer = DllStructGetPtr($tBuffer) DllStructSetData($tItem, "Text", $pBuffer) DllStructSetData($tItem, "TextMax", 2048) DllStructSetData($tItem, "Mask", BitOR($LVIF_TEXT, $LVIF_PARAM)) DllStructSetData($tItem, "Item", 999999999) DllStructSetData($tItem, "Image", -1) Do $msg = GUIGetMsg() Select Case $msg = $button1 _SendMessage($hlistview,$WM_SETREDRAW,0,0) ;~ _GUICtrlListView_BeginUpdate($ListView) $start = TimerInit() For $i = 1 To 4000 GUICtrlCreateListViewItem("item1|col2|col3", $listview) Next GUICtrlSetData($input1, 'Time: ' & TimerDiff($start)) _SendMessage($hlistview,$WM_SETREDRAW,1,0) ;~ _GUICtrlListView_EndUpdate($ListView) ; 440/310 ms (650/280) Case $msg = $button2 _SendMessage($hlistview,$WM_SETREDRAW,0,0) $start = TimerInit() For $i = 1 To 4000 ;~ _GUICtrlListView_AddItem($ListView, "item1|col2|col3") ;~ _GUICtrlListView_AddItem($hListView, "item1|col2|col3") _GUICtrlListView_InsertItem_Optim($ListView, "item1|col2|col3") Next GUICtrlSetData($input1, 'Time: ' & TimerDiff($start)) _SendMessage($hlistview,$WM_SETREDRAW,1,0) ; 1250/1120 ms with $ListView (2650/2000) ; 1980/1850ms with $hListView (12000/9280) ; 365/240 optim with $ListView Case $msg = $button3 _GUICtrlListView_DeleteAllItems($hListView) EndSelect Until $msg = $GUI_EVENT_CLOSE Func _GUICtrlListView_InsertItem_Optim($hWnd, $sText) DllStructSetData($tItem, "Param", GUICtrlSendMsg($hWnd, $LVM_GETITEMCOUNT, 0, 0)) DllStructSetData($tBuffer, "Text", $sText) Return GUICtrlSendMsg($hWnd, $LVM_INSERTITEMA, 0, $pItem) EndFunc Edited April 4, 2008 by Zedna Resources UDF ResourcesEx UDF AutoIt Forum Search Link to comment Share on other sites More sharing options...
Zedna Posted April 4, 2008 Author Share Posted April 4, 2008 (edited) Here is optimized version which is even quicker than native one!But I noticed that UDF and also my optimized UDF only adds first column and not all subitems like native one.So I will create also test for all subitems.Note: Times are: without WM_SETREDRAW / with $WM_SETREDRAW = 0 native: 440/310 ms UDF: 1250/1120 msUDF optimized: 365/240 msI changed previous test only for adding 1 (first) column so it could be comparable between native and UDF versionHere are results:Note: Times are: with $WM_SETREDRAW = 0 native: 110 ms UDF: 1125 msUDF optimized: 235 ms Edited April 4, 2008 by Zedna Resources UDF ResourcesEx UDF AutoIt Forum Search Link to comment Share on other sites More sharing options...
Zedna Posted April 4, 2008 Author Share Posted April 4, 2008 (edited) I changed previous test only for adding 1 (first) column so it could be comparable between native and UDF version Here are results: Note: Times are: with $WM_SETREDRAW = 0 native: 110 ms UDF: 1125 ms UDF optimized: 235 ms I removed $LVIF_PARAM and DllStructSetData($tItem, "Param", GUICtrlSendMsg($hWnd, $LVM_GETITEMCOUNT, 0, 0)) in my optimized UDF version and results is UDF optimized: 160 ms (without LVIF_PARAM) expandcollapse popup#include <GUIConstants.au3> #include <GUIListView.au3> $gui = GUICreate("listview items", 320, 250, 100, 200) $listview = GUICtrlCreateListView("col1 ", 10, 10, 200, 150);,$LVS_SORTDESCENDING) $hListView = ControlGetHandle($gui, '', $listview) $button1 = GUICtrlCreateButton("Create std", 15, 170, 70, 20) $button2 = GUICtrlCreateButton("Create UDF", 125, 170, 70, 20) $button3 = GUICtrlCreateButton("Delete UDF", 200, 170, 70, 20) $input1 = GUICtrlCreateInput("", 20, 200, 150) GUISetState() Global $pBuffer, $tBuffer, $pItem, $tItem $tItem = DllStructCreate($tagLVITEM) $pItem = DllStructGetPtr($tItem) $tBuffer = DllStructCreate("char Text[2048]") $pBuffer = DllStructGetPtr($tBuffer) DllStructSetData($tItem, "Text", $pBuffer) DllStructSetData($tItem, "TextMax", 2048) DllStructSetData($tItem, "Mask", $LVIF_TEXT) DllStructSetData($tItem, "Item", 999999999) DllStructSetData($tItem, "Image", -1) Do $msg = GUIGetMsg() Select Case $msg = $button1 _SendMessage($hlistview,$WM_SETREDRAW,0,0) ;~ _GUICtrlListView_BeginUpdate($ListView) $start = TimerInit() For $i = 1 To 4000 GUICtrlCreateListViewItem("item1", $listview) Next GUICtrlSetData($input1, 'Time: ' & TimerDiff($start)) _SendMessage($hlistview,$WM_SETREDRAW,1,0) ;~ _GUICtrlListView_EndUpdate($ListView) ; 440/310 ms (650/280) Case $msg = $button2 _SendMessage($hlistview,$WM_SETREDRAW,0,0) $start = TimerInit() For $i = 1 To 4000 ;~ _GUICtrlListView_AddItem($ListView, "item1") ;~ _GUICtrlListView_AddItem($hListView, "item1") _GUICtrlListView_InsertItem_Optim($ListView, "item1") Next GUICtrlSetData($input1, 'Time: ' & TimerDiff($start)) _SendMessage($hlistview,$WM_SETREDRAW,1,0) ; 1250/1120 ms with $ListView (2650/2000) ; 1980/1850ms with $hListView (12000/9280) ; 365/240 optim with $ListView Case $msg = $button3 _GUICtrlListView_DeleteAllItems($hListView) EndSelect Until $msg = $GUI_EVENT_CLOSE Func _GUICtrlListView_InsertItem_Optim($hWnd, $sText) DllStructSetData($tBuffer, "Text", $sText) Return GUICtrlSendMsg($hWnd, $LVM_INSERTITEMA, 0, $pItem) EndFunc Edited April 4, 2008 by Zedna Resources UDF ResourcesEx UDF AutoIt Forum Search Link to comment Share on other sites More sharing options...
Zedna Posted April 4, 2008 Author Share Posted April 4, 2008 Now I randomly noticed there is _GUICtrlListView_AddArray() function which is based on the same optimization idea!! So I found America once again today Resources UDF ResourcesEx UDF AutoIt Forum Search Link to comment Share on other sites More sharing options...
GaryFrost Posted April 4, 2008 Share Posted April 4, 2008 Now I randomly noticed there is _GUICtrlListView_AddArray() function which is based on the same optimization idea!!So I found America once again today It happens. Can't remember everything I've done. SciTE for AutoItDirections for Submitting Standard UDFs Don't argue with an idiot; people watching may not be able to tell the difference. Link to comment Share on other sites More sharing options...
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now