Jump to content

Optimized Array.au3


-Ultima-
 Share

Recommended Posts

George,

Which part are you missing in the build-in Ubound version ?

$rows = UBound($myArray)
$cols = UBound($myArray, 2)
$dims = UBound($myArray, 0)

;)

:P

Thanks my most highly esteemed wise man! Just when I thought I had discovered something that we needed too! Actually I forgot that there were parameters for Ubound() :D

Edit: Now that you have brought this back to my attention, let me just say this about that, the documentation on the Dimension parameter is not really well done. :P

Edited by GEOSoft

George

Question about decompiling code? Read the decompiling FAQ and don't bother posting the question in the forums.

Be sure to read and follow the forum rules. -AKA the AutoIt Reading and Comprehension Skills test.***

The PCRE (Regular Expression) ToolKit for AutoIT - (Updated Oct 20, 2011 ver:3.0.1.13) - Please update your current version before filing any bug reports. The installer now includes both 32 and 64 bit versions. No change in version number.

Visit my Blog .. currently not active but it will soon be resplendent with news and views. Also please remove any links you may have to my website. it is soon to be closed and replaced with something else.

"Old age and treachery will always overcome youth and skill!"

Link to comment
Share on other sites

  • Replies 137
  • Created
  • Last Reply

Top Posters In This Topic

Top Posters In This Topic

  • Developers

Edit: Now that you have brought this back to my attention, let me just say this about that, the documentation on the Dimension parameter is not really well done. :D

Yea, you gotta blame something for your oversight :P

SciTE4AutoIt3 Full installer Download page   - Beta files       Read before posting     How to post scriptsource   Forum etiquette  Forum Rules 
 
Live for the present,
Dream of the future,
Learn from the past.
  :)

Link to comment
Share on other sites

Yea, you gotta blame something for your oversight :D

It could have been worse, I could have said that you taught me all I know. :P Actually if I read the page enough times I can see it. However, I'm almost certain that nobody wore out a keyboard when explaining it. Now if it showed an example such as you gave me then I would have no excuse, not even a weak one like this.

You just keep ruining my day, I really thrive on abuse.

George

Question about decompiling code? Read the decompiling FAQ and don't bother posting the question in the forums.

Be sure to read and follow the forum rules. -AKA the AutoIt Reading and Comprehension Skills test.***

The PCRE (Regular Expression) ToolKit for AutoIT - (Updated Oct 20, 2011 ver:3.0.1.13) - Please update your current version before filing any bug reports. The installer now includes both 32 and 64 bit versions. No change in version number.

Visit my Blog .. currently not active but it will soon be resplendent with news and views. Also please remove any links you may have to my website. it is soon to be closed and replaced with something else.

"Old age and treachery will always overcome youth and skill!"

Link to comment
Share on other sites

  • Developers

... Now if it showed an example such as you gave me then I would have no excuse, not even a weak one like this.

You just keep ruining my day, I really thrive on abuse.

ok... I give you one chance to guess where I got that example I gave from ... :D

SciTE4AutoIt3 Full installer Download page   - Beta files       Read before posting     How to post scriptsource   Forum etiquette  Forum Rules 
 
Live for the present,
Dream of the future,
Learn from the past.
  :)

Link to comment
Share on other sites

ok... I give you one chance to guess where I got that example I gave from ... :D

How about that !! My help file viewer has a scroll bar on it !!

Oh well, I can't win all the time (once in a while would be good though).

Now please excuse me while I beat myself to death with a hammer.

George

Question about decompiling code? Read the decompiling FAQ and don't bother posting the question in the forums.

Be sure to read and follow the forum rules. -AKA the AutoIt Reading and Comprehension Skills test.***

The PCRE (Regular Expression) ToolKit for AutoIT - (Updated Oct 20, 2011 ver:3.0.1.13) - Please update your current version before filing any bug reports. The installer now includes both 32 and 64 bit versions. No change in version number.

Visit my Blog .. currently not active but it will soon be resplendent with news and views. Also please remove any links you may have to my website. it is soon to be closed and replaced with something else.

"Old age and treachery will always overcome youth and skill!"

Link to comment
Share on other sites

As I'm working on array sorting solution for myself right now, decided to check out current trends around here. Haven't read entire thread, just skimmed through several pages of arguing over speed percentages :D Only of ArrayDisplay I understand, not sorting?

I'll say this -

Lets take that test.au3 attached to this post for example, with 10k array size.

As I understand, it runs in around 2-4 seconds for you guys? That's fine, but it's just more of an example that the power of modern systems with all the dual cores, 2+ gigs of RAM, etc. can hide fundamental design flaws pretty well.

On my modest PC it takes 10-15 secs. Not that cool anymore. Up the array size to 40k and it takes over a minute. And so on.

Granted, most users won't be running this on arrays that big, far from it; and of those few who will, most will have enough PC power to handle it reasonably fast.

But in such case it's not worth arguing about "optimizing" it at all that much, is it... :P

And if you want fast loading times, proper option would be virtual listview:

#include <GuiListView.au3>
#Include <GuiEdit.au3>
;~ #AutoIt3Wrapper_useansi=y

$width = 5
$height = 10000
Global $a[$height][$width]
for $i = 0 to $height-1
    for $j = 0 to $width-1
        $a[$i][$j] = $i & "|" & $j
    next
next

;The array and text buffer have to be Global! Either set by the user ,or through Assign() inside the func.
$sTextBuff = "char[261]" 
If @Unicode Then $sTextBuff = "w" & $sTextBuff
Global $tTextBuffer = DllStructCreate($sTextBuff)


_ArrayDisplayVirt($a)
;~ _arraydisplaycurr($a)


Func _ArrayDisplayVirt(Const ByRef $avArray, $sTitle = "Array: ListView Display", $iItemLimit = -1, $iTranspose = 0, $sSeparator = "", $sReplace = "|")
Local $timer = TimerInit()
    If Not IsArray($avArray) Then Return SetError(1, 0, 0)

    ; Dimension checking
    Local $iDimension = UBound($avArray, 0), $iUBound = UBound($avArray, 1) - 1, $iSubMax = UBound($avArray, 2) - 1
    If $iDimension > 2 Then Return SetError(2, 0, 0)

    ; Separator handling
    If $sSeparator = "" Then $sSeparator = Chr(1)

    ; Declare variables
    Local $i, $j, $vTmp, $aItem, $avArrayText, $sHeader = "Row", $iBuffer = 64
    Local $iColLimit = 200, $iLVIAddUDFThreshold = 4000, $iWidth = 640, $iHeight = 480
    Local $iOnEventMode = Opt("GUIOnEventMode", 0), $sDataSeparatorChar = Opt("GUIDataSeparatorChar", $sSeparator)

    ; Swap dimensions if transposing
    If $iSubMax < 0 Then $iSubMax = 0
    If $iTranspose Then
        $vTmp = $iUBound
        $iUBound = $iSubMax
        $iSubMax = $vTmp
    EndIf

    ; Set limits for dimensions
    If $iSubMax > $iColLimit Then $iSubMax = $iColLimit
    If $iItemLimit = 1 Then $iItemLimit = $iLVIAddUDFThreshold
    If $iItemLimit < 1 Then $iItemLimit = $iUBound
    If $iUBound > $iItemLimit Then $iUBound = $iItemLimit
    If $iLVIAddUDFThreshold > $iUBound Then $iLVIAddUDFThreshold = $iUBound

    ; Set header up
    For $i = 0 To $iSubMax
        $sHeader &= $sSeparator & "[" & $i & "]"
    Next

    ; GUI Constants

;;virtual lv style
    Local Const $LVS_OWNERDATA = 0x1000
    
    
    Local Const $_ARRAYCONSTANT_GUI_DOCKBORDERS = 0x66
    Local Const $_ARRAYCONSTANT_GUI_DOCKBOTTOM = 0x40
    Local Const $_ARRAYCONSTANT_GUI_DOCKHEIGHT = 0x0200
    Local Const $_ARRAYCONSTANT_GUI_DOCKLEFT = 0x2
    Local Const $_ARRAYCONSTANT_GUI_DOCKRIGHT = 0x4
    Local Const $_ARRAYCONSTANT_GUI_EVENT_CLOSE = -3
    Local Const $_ARRAYCONSTANT_LVIF_PARAM = 0x4
    Local Const $_ARRAYCONSTANT_LVIF_TEXT = 0x1
    Local Const $_ARRAYCONSTANT_LVM_GETITEMCOUNT = (0x1000 + 4)
    Local Const $_ARRAYCONSTANT_LVM_GETITEMSTATE = (0x1000 + 44)
    Local Const $_ARRAYCONSTANT_LVM_INSERTITEMA = (0x1000 + 7)
    Local Const $_ARRAYCONSTANT_LVM_SETEXTENDEDLISTVIEWSTYLE = (0x1000 + 54)
    Local Const $_ARRAYCONSTANT_LVM_SETITEMA = (0x1000 + 6)
    Local Const $_ARRAYCONSTANT_LVS_EX_FULLROWSELECT = 0x20
    Local Const $_ARRAYCONSTANT_LVS_EX_GRIDLINES = 0x1
    Local Const $_ARRAYCONSTANT_LVS_SHOWSELALWAYS = 0x8
    Local Const $_ARRAYCONSTANT_WS_EX_CLIENTEDGE = 0x0200
    Local Const $_ARRAYCONSTANT_WS_MAXIMIZEBOX = 0x00010000
    Local Const $_ARRAYCONSTANT_WS_MINIMIZEBOX = 0x00020000
    Local Const $_ARRAYCONSTANT_WS_SIZEBOX = 0x00040000
    Local Const $_ARRAYCONSTANT_tagLVITEM = "int Mask;int Item;int SubItem;int State;int StateMask;ptr Text;int TextMax;int Image;int Param;int Indent;int GroupID;int Columns;ptr pColumns"

    Local $iAddMask = BitOR($_ARRAYCONSTANT_LVIF_TEXT, $_ARRAYCONSTANT_LVIF_PARAM)
    Local $tBuffer = DllStructCreate("char Text[" & $iBuffer & "]"), $pBuffer = DllStructGetPtr($tBuffer)
    Local $tItem = DllStructCreate($_ARRAYCONSTANT_tagLVITEM), $pItem = DllStructGetPtr($tItem)
    DllStructSetData($tItem, "Param", 0)
    DllStructSetData($tItem, "Text", $pBuffer)
    DllStructSetData($tItem, "TextMax", $iBuffer)

    ; Set interface up
    Local $hGUI = GUICreate($sTitle, $iWidth, $iHeight, Default, Default, BitOR($_ARRAYCONSTANT_WS_SIZEBOX, $_ARRAYCONSTANT_WS_MINIMIZEBOX, $_ARRAYCONSTANT_WS_MAXIMIZEBOX))
    Local $aiGUISize = WinGetClientSize($hGUI)
    Local $hListView = GUICtrlCreateListView($sHeader, 0, 0, $aiGUISize[0], $aiGUISize[1] - 26, $_ARRAYCONSTANT_LVS_SHOWSELALWAYS+$LVS_OWNERDATA)

    Local $hCopy = GUICtrlCreateButton("Copy Selected", 3, $aiGUISize[1] - 23, $aiGUISize[0] - 6, 20)

    GUICtrlSetResizing($hListView, $_ARRAYCONSTANT_GUI_DOCKBORDERS)
    GUICtrlSetResizing($hCopy, $_ARRAYCONSTANT_GUI_DOCKLEFT + $_ARRAYCONSTANT_GUI_DOCKRIGHT + $_ARRAYCONSTANT_GUI_DOCKBOTTOM + $_ARRAYCONSTANT_GUI_DOCKHEIGHT)
    GUICtrlSendMsg($hListView, $_ARRAYCONSTANT_LVM_SETEXTENDEDLISTVIEWSTYLE, $_ARRAYCONSTANT_LVS_EX_GRIDLINES, $_ARRAYCONSTANT_LVS_EX_GRIDLINES)
    GUICtrlSendMsg($hListView, $_ARRAYCONSTANT_LVM_SETEXTENDEDLISTVIEWSTYLE, $_ARRAYCONSTANT_LVS_EX_FULLROWSELECT, $_ARRAYCONSTANT_LVS_EX_FULLROWSELECT)
    GUICtrlSendMsg($hListView, $_ARRAYCONSTANT_LVM_SETEXTENDEDLISTVIEWSTYLE, $_ARRAYCONSTANT_WS_EX_CLIENTEDGE, $_ARRAYCONSTANT_WS_EX_CLIENTEDGE)
GUICtrlSendMsg($hListView, $_ARRAYCONSTANT_LVM_SETEXTENDEDLISTVIEWSTYLE, $LVS_EX_DOUBLEBUFFER, $LVS_EX_DOUBLEBUFFER)

For $i = 0 To $iColLimit ;;fix columns width
    GUICtrlSendMsg($hListView, 0x101E, $i, 50) ;;LVM_SETCOLUMNWIDTH = 0x101E
Next

GUICtrlSendMsg($hListView, $LVM_SETITEMCOUNT, $iUBound+1, 0) ;;set total item count - necessary for virtual lv

Local $wProcNew = DllCallbackRegister("_ArrayUDF_WM_NOTIFY", "ptr", "hwnd;uint;long;ptr") ;;register new window proc
Local $wProcOld = _ArrayUDF_WinSubclass($hGUI, DllCallbackGetPtr($wProcNew)) ;;sublass gui
Assign('ArrayUDF_wProcOld', $wProcOld, 2) ;; $ArrayUDF_wProcOld = global keeper of old windowproc ptr

consolewrite(timerdiff($timer)/1000 & @CRLF)
    ; Show dialog
    GUISetState(@SW_SHOW, $hGUI)
    While 1
        Switch GUIGetMsg()
            Case $_ARRAYCONSTANT_GUI_EVENT_CLOSE
                ExitLoop

            Case $hCopy
                Local $sClip = ""

                ; Get selected indices [ _GUICtrlListView_GetSelectedIndices($hListView, True) ]
                Local $aiCurItems[1] = [0]
                For $i = 0 To GUICtrlSendMsg($hListView, $_ARRAYCONSTANT_LVM_GETITEMCOUNT, 0, 0)
                    If GUICtrlSendMsg($hListView, $_ARRAYCONSTANT_LVM_GETITEMSTATE, $i, 0x2) Then
                        $aiCurItems[0] += 1
                        ReDim $aiCurItems[$aiCurItems[0] + 1]
                        $aiCurItems[$aiCurItems[0]] = $i
                    EndIf
                Next
                ; Generate clipboard text
                If Not $aiCurItems[0] Then
                    For $sItem In $a
                        $sClip &= $sItem & @CRLF
                    Next
                Else
                    ;;copy stuff
                    For $i = 1 To UBound($aiCurItems) - 1
                        $sClip &= "[" & $i-1 & "]"
                        ConsoleWrite('$isubmax=' & $iSubMax & @CRLF)
                        For $j = 0 To $iSubMax
                            $sClip &=  Chr(1) & $a[$aiCurItems[$i]][$j]
                        Next
                        $sClip &= @CRLF
                    Next

                EndIf
                ClipPut($sClip)
        EndSwitch
    WEnd
    _ArrayUDF_WinSubclass($hGUI, $wProcOld) ;;restore old proc on exit
    DllCallbackFree($wProcNew) ;;free callback
    GUIDelete($hGUI)

    Opt("GUIOnEventMode", $iOnEventMode)
    Opt("GUIDataSeparatorChar", $sDataSeparatorChar)

    Return 1
EndFunc
Func _ArrayUDF_WM_NOTIFY($hWnd, $Msg, $wParam, $lParam)

    Local $wProcOld = Eval('ArrayUDF_wProcOld'), $i, $j, $tNMLVDISPINFO, $text, $textlen, $maxlen
;;$WM_NOTIFY = 0x004E
    If $Msg <> 0x004E Then Return _ArrayUDF_CallWndProc($wProcOld, $hWnd, $Msg, $wParam, $lParam)

    Local $tNMHDR = DllStructCreate("hwnd hwndfrom;int idfrom;int code", $lParam)
    Local $hWndFrom = DllStructGetData($tNMHDR, "hwndfrom"), $iCode = DllStructGetData($tNMHDR, "code")

    ;; the following is not very good, better would be have listview handle available in global scope.
    If ControlGetHandle($hWnd, "", "[Class:SysListView32;Instance:1]") = $hWndFrom Then

        Switch $iCode
            Case -150, -177 ;;$LVN_GETDISPINFOA = -150, $LVN_GETDISPINFOW = -177
                ;;give requested items one by one (kinda slow if a lot of items are visible at the same time)
                $tNMLVDISPINFO = DllStructCreate("hwnd hwndfrom;int idfrom;int code;" & _
                "uint mask;int item;int subitem;uint state;uint statemask;ptr text;int textmax;int;dword lparam;int;uint[5]", $lParam)

                If BitAND(DllStructGetData($tNMLVDISPINFO, "mask"), $LVIF_TEXT) Then
                    $i = Dec(Hex(DllStructGetData($tNMLVDISPINFO, "item")))
                    $j = DllStructGetData($tNMLVDISPINFO, "subitem")

                    If $j = 0 Then
                        $text = "[" & $i & "]"
                    Else
                        $text = $a[$i][$j-1]
                    EndIf
                    $textlen = StringLen($text)
                    $maxlen = DllStructGetSize($tTextBuffer)
                    If @Unicode Then $maxlen = $maxlen/2
                    If $textlen > $maxlen-1 Then $text = StringLeft($text, $maxlen-1)

                    DllStructSetData($tTextBuffer, 1, $text)
                    DllStructSetData($tNMLVDISPINFO, "textmax", $textlen)
                    DllStructSetData($tNMLVDISPINFO, "text", DllStructGetPtr($tTextBuffer))
                ElseIf BitAND(DllStructGetData($tNMLVDISPINFO, "mask"), $LVIF_STATE) Then
                    ;;meh. although the selected items array filling could be implemented here, so there wouldn't be no need
                    ;;to loop through entire thing again when "Copy Selected" button is clicked

                EndIf
            Case -152, -179 ;;$LVN_ODFINDITEM = -152, $LVN_ODFINDITEMW = -179
                ;;lv keyboard find functionality.
                If UBound($a, 0) <> 1 Then Return -1
                $tNMLVFINDITEM = DllStructCreate("hwnd hwndfrom;int idfrom;int code;" & _
                "int start;uint flags;ptr string;dword lparam;int pointx;int pointy;uint dir", $lParam)
                If BitAND(DllStructGetData($tNMLVFINDITEM, "flags"), $LVFI_STRING) = 0 Then ContinueCase
                Local $sStructSearch = "char[260]"
                If @Unicode Then $sStructSearch = "w" & $sStructSearch
                Local $tSearchStr = DllStructCreate($sStructSearch, DllStructGetData($tNMLVFINDITEM, "string"))
                Local $sSearchString = DllStructGetData($tSearchStr, 1)
                ConsoleWrite($sSearchString & @CRLF)
                $i = _ArraySearch($a, $sSearchString)
                If Not @error Then
                    Return $i
                EndIf
                Return -1
            Case -113 ;$LVN_OCACHEHINT = -113
                ;;cache data to make it faster. not quite sure how it works
;~              Local $tNMLVCACHEHINT = DllStructCreate("hwnd hwndfrom;int idfrom;int code;" & _
;~                                                      "int from;int to", $lParam)
;~              $iFrom = DllStructGetData($tNMLVCACHEHINT, "from")
;~              $iTo = DllStructGetData($tNMLVCACHEHINT, "to")
;~              ConsoleWrite('- chache: from ' & $iFrom & ' to ' & $iTo & @CRLF)
        EndSwitch
    EndIf

    ;;pass the unhandled messages to default WindowProc
    Return _ArrayUDF_CallWndProc($wProcOld, $hWnd, $Msg, $wParam, $lParam)

EndFunc
Func _ArrayUDF_WinSubclass($hWnd, $lpNewWindowProc)
    ;#define GWL_WNDPROC (-4)
    Local $aTmp, $sFunc = "SetWindowLong"
    If @Unicode Then $sFunc &= "W"
    $aTmp = DllCall("user32.dll", "ptr", $sFunc, "hwnd", $hWnd, "int", -4, "ptr", $lpNewWindowProc)
    If @error Then Return SetError(1, 0, 0)
    If $aTmp[0] = 0 Then Return SetError(1, 0, 0)
    Return $aTmp[0]
EndFunc   ;==>_WinSubclass
Func _ArrayUDF_CallWndProc($lpPrevWndFunc, $hWnd, $Msg, $wParam, $lParam)
    Local $aRet = DllCall('user32.dll', 'uint', 'CallWindowProc', 'ptr', $lpPrevWndFunc, 'hwnd', $hWnd, 'uint', $Msg, 'wparam', $wParam, 'lparam', $lParam)
;~  If @error Then Return 0
    Return $aRet[0]
EndFunc

Not finished - main thing only works on 2D array (was too lazy to add cases for 1D), keyboard search doesn't work on 2D arrray (no search functions for 2D available in official Array UDF), some redundant stuff probably left over because I just wrote it on top of one function in test.au3, etc. etc.

But that shouldn't be hard to complete. If you chose to. And if not, then it doesn't really matter, and that's why I decided not to waste more time on it.

Also exemplifies subclassing of parent gui to get access to notification messages without GuiRegisterMsg (which would kill user's handler if user happens to have registered the same msg too).

Edited by Siao

"be smart, drink your wine"

Link to comment
Share on other sites

Can we do a sort on selected column as Virtual too!

If you have array sorter, you can hook it up on lv header mouse click. Sort the array and force redraw listview.

Virtual listview doesn't have actual data by itself (other than selected item state), text (and images/checkboxes/etc, if any) must be provided when requested by listview with a LVN_GETDISPINFO notification. Which makes scrolling through the list kinda laggy if there are lot of visible items, because each item and subitem is updated separately. There's supposedly some caching functionality to remedy that, but I 've never gotten into researching it...

Edited by Siao

"be smart, drink your wine"

Link to comment
Share on other sites

If you have array sorter, you can hook it up on lv header mouse click. Sort the array and force redraw listview.

Virtual listview doesn't have actual data by itself (other than selected item state), text (and images/checkboxes/etc, if any) must be provided when requested by listview with a LVN_GETDISPINFO notification. Which makes scrolling through the list kinda laggy if there are lot of visible items, because each item and subitem is updated separately. There's supposedly some caching functionality to remedy that, but I 've never gotten into researching it...

Thanks again!

So how?..

Case $hListView
        ;do the sort on array, then
        GUICtrlSendMsg($hListView, LVN_GETDISPINFO ,,)
?

Some parameters perhaps?...

Sorry to be so slow..

Best, Randall

Edited by randallc
Link to comment
Share on other sites

;in _ArrayUDF_WM_NOTIFY():
    ;...
        Switch $iCode
        ;...
            Case $LVN_COLUMNCLICK
                $tNMLISTVIEW = DllStructCreate("hwnd hwndfrom;int idfrom;int code;" & _
                "int item;int subitem", $lParam)
                $iCol = DllStructGetData($tNMLISTVIEW, "subitem")
                _GUICtrlListView_BeginUpdate($hWndFrom)
            ;now sort the array depending on $iCol
            ;
                _GUICtrlListView_EndUpdate($hWndFrom)

"be smart, drink your wine"

Link to comment
Share on other sites

Is there anywhere I can read up a bit on it?; I vaguely know the ideas only.

MSDN windows user interface, and in particular common controls, reference is pretty handy. It has all the controls listed separately, each with overview section, where the general principles are outlined - what and how you can do with a particular control, etc., and reference section, where all the possible functions/messages/notifications/structs are documented.

Then it's a matter of stuffing all that information together with the means available in AutoIt and seeing what comes out of it... :D

"be smart, drink your wine"

Link to comment
Share on other sites

As I'm working on array sorting solution for myself right now,

Hi,

1.This is disappointing, as it is so fantastic for displays of large numbers of rows, up to 5-10x as fast, when adjusted!- yet 5-10x slower and completely unusable for lateral scrolling if there are any decent numbers of columns; even over 20-50, let alone thousands! - is there any way to fix that!?

2. Did you see my ArrayDisplay with sorting?; and my array sorting solutions? Can you do better, as I'm still looking..

Best, randall

Link to comment
Share on other sites

Hi,

1.This is disappointing, as it is so fantastic for displays of large numbers of rows, up to 5-10x as fast, when adjusted!- yet 5-10x slower and completely unusable for lateral scrolling if there are any decent numbers of columns; even over 20-50, let alone thousands! - is there any way to fix that!?

2. Did you see my ArrayDisplay with sorting?; and my array sorting solutions? Can you do better, as I'm still looking..

Best, randall

1. I warned you of this, didn't I? :P Because every time you scroll, (visible rows) * (total columns) of cell text needs to be updated.

There's supposedly some caching with LVN_ODCACHEHINT notification, but I guess that wouldn't be of any use in AutoIt (though I may be wrong), and is meant for cases when the data is in DB and caching a range to some memory buffer for faster retrieval during LVN_GETDISPINFO would be more efficient than db querrying it one by one...

You can trim some unnecessary operations I left in LVN_GETDISPINFO (such as all the StringLen/StringLetft stuff, DllStructGetPtr if you move it to Global scope) maybe it will help a little bit.

But I'm afraid the real cure is simply not to have that many items visible at one time. If you size the window to have only 10-15 rows visible, it's not that bad. If you maximize the window and have 40+ rows visible at a time, multiply that by total columns, then it's another story.

I guess the bottom line is that, if you have the need for a proper data grid (with a "decent" 20+ columns and thousands of items), then a common listview implemented in Autoit isn't the best solution anyway.

Thing is, I haven't tinkered with it to that extent, and right now I have no time for it. I've been using it in a couple of my apps to display thousands of items, but only with 1-2 colums, and as you can imagine it works well on that.

There might be some ways to optimize the performance.

Skipping update of invisible columns somehow (_GUICtrlListView_GetSubItemRect should work, if x2 coord is less than 0 and x1 is greater than lv width it means that column isn't visible, and you can do this check on LVN_ODCACHEHINT once to global variables $ColStart & $ColEnd, and then on LVN_GETDISPINFO do update just that range) comes to mind in particular. Don't know why that thing requests all columns if it doesn't make use of that and still keeps requesting all columns on horizontal scroll. Seems just stupid to me.

Maybe something else too, if you give it a good thought.

2. Frankly, I don't expect the sorter I'm working on to do better than your vbs/js solutions time-wise, because no matter how you slice it, autoit array format (and specifically, getting the sorted data back to it) is the bottleneck in my case, but it still should blow away any algo implementation in "pure" AutoIt.

Now that you mention it, I'd like to see what solution are you currently using for 1D/2D sorting (with ascending/descending, case (in)sensitive options), with link and ready to use plz. I have some of your files, but I don't know if they are the latest versions, and it's a bit of a pain to use them regardless - getting to know what is what in there and how to set it up :D

Edited by Siao

"be smart, drink your wine"

Link to comment
Share on other sites

Hi,

Thanks for that.

1. Unfortunately, I stopped working on your display for sort when I realised the column problem, but now I know it is OK for 1D and 2D with columns up to about 10, i will have another go, as I think it is worth it!

2. Here is the link to my last posted display with sort; I think it crashes with your exact array at present, so leave out "|" if you are testing 2D. OK sort speed to about 5000X5, depending..

Fast New ArrayDisplay with Fast Sort,

3. -Descending/ Asc- Although there is still vbs code in the sort for "ArrayReverse", it is not used, and I found a simple AutoIt ArrayReverse was easy at the time, and quite fast!

4. -Case- It is also in the vbs code, but I have been using case-insensitive and haven't tested case- sensitive lately; it automatically checks if all items in a column can be sorted -sensitive- if all numbers..

5. Sorry it is so messy. There is another version nearly ready, and I may go away from trying to put it all in 1 func again, as it is so messy...

Best, Randall.

PS I will try to put together some full examples too.. not all there as you requested as yet

Edited by randallc
Link to comment
Share on other sites

Hi,

@Siao, I have used your Display to great advantage for columns up tp 5;

Please let me know if you find any bugs.. [note the fast sort speeds are for case-sensitive, I fear!]

I have changed to fantastic fast display, thanks @Siao!

3 x10,000 array ;

displays in 0.3 secs max.

Sorts by column in about 1 sec (10,000/sec) (dealy after Display till ready to sort of 0.5sec, usually half the sort time)

Reverts to "_ArrayDispalySort" UDF included if more columns than 5...

Displays 1D, 2D, , or 1D array of strings (eg filereadToArray of a csv)

Fast New ArrayDisplay with Fast Sort(Virtual)

Best, randall

Edited by randallc
Link to comment
Share on other sites

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 account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...