_GUICtrlListView_GetSelectedIndices ist langsam bei Array-Rückgabe

    • Offizieller Beitrag

    Mir ist gerade aufgefallen, dass die Funktion "_GUICtrlListView_GetSelectedIndices" bei Array-Rückgabe noch ein ReDim innerhalb der For...Next-Schleife benutzt.
    Das ist ziemlich zeitfressend, wenn man viele Listview-Einträge benutzt. Deshalb habe ich die Funktion mal umgeschrieben. Das Ergebnis ist umso gravierender, je mehr Listview-Einträge vorhanden sind:

    Spoiler anzeigen
    [autoit]


    #include <GuiListView.au3>
    #include <ListViewConstants.au3>
    #include <SendMessage.au3>

    [/autoit] [autoit][/autoit] [autoit]

    $hGui = GUICreate('Listview-Test', 400, 600)
    $hListView = GUICtrlCreateListView('a|b|c|d', 5, 5, 390, 590, $LVS_SHOWSELALWAYS)
    For $i = 0 To 4999
    $sItem = Random(1000, 9999, 1) & '|' & Random(1000, 9999, 1) & '|' & Random(1000, 9999, 1) & '|' & Random(1000, 9999, 1)
    GUICtrlCreateListViewItem($sItem, $hListView)
    Next
    GUISetState()
    $hWndLV = GUICtrlGetHandle($hListView)
    _GUICtrlListView_SetItemSelected($hWndLV, -1, True)
    $iTimer = TimerInit()
    $aSelIndices = _GUICtrlListView_GetSelectedIndices($hListView, True) ; das Original
    ConsoleWrite('Original: ' & TimerDiff($iTimer) & @CR)
    $iTimer = TimerInit()
    $aSelIndices = _GUICtrlListView_GetSelectedIndicesNew($hListView, True) ; die modifizierte Version (unten)
    ConsoleWrite('Modifiziert: ' & TimerDiff($iTimer) & @CR)
    Do
    Until GUIGetMsg() = -3

    [/autoit] [autoit][/autoit] [autoit]

    ; #FUNCTION# ====================================================================================================================
    ; Name...........: _GUICtrlListView_GetSelectedIndicesNew
    ; Description ...: Retrieve indices of selected item(s)
    ; Syntax.........: _GUICtrlListView_GetSelectedIndices($hWnd, $fArray = False)
    ; Parameters ....: $hWnd - Handle to the control
    ; $fArray - Return string or Array
    ; |True - Returns array
    ; |False - Returns pipe "|" delimited string
    ; Return values .: Success - Selected indices Based on $fArray:
    ; +Array - With the following format
    ; |[0] - Number of Items in array (n)
    ; |[1] - First item index
    ; |[2] - Second item index
    ; |[n] - Last item index
    ; |String - With the following format
    ; |"0|1|2|n"
    ; Failure - Based on $fArray
    ; |Array - With the following format
    ; |[0] - Number of Items in array (0)
    ; |String - Empty ("")
    ; Author ........: Gary Frost (gafrost)
    ; Modified.......:
    ; Remarks .......:
    ; Related .......:
    ; Link ..........:
    ; Example .......: Yes
    ; ===============================================================================================================================
    Func _GUICtrlListView_GetSelectedIndicesNew($hWnd, $fArray = False)
    If $Debug_LV Then __UDF_ValidateClassName($hWnd, $__LISTVIEWCONSTANT_ClassName)

    [/autoit] [autoit][/autoit] [autoit]

    Local $sIndices, $iRet, $iCount = _GUICtrlListView_GetItemCount($hWnd)
    For $iItem = 0 To $iCount
    If IsHWnd($hWnd) Then
    $iRet = _SendMessage($hWnd, $LVM_GETITEMSTATE, $iItem, $LVIS_SELECTED)
    Else
    $iRet = GUICtrlSendMsg($hWnd, $LVM_GETITEMSTATE, $iItem, $LVIS_SELECTED)
    EndIf
    If $iRet Then $sIndices &= $iItem & '|'
    Next
    If $fArray Then Return StringSplit(StringTrimRight($sIndices, 1), '|')
    Return StringTrimRight($sIndices, 1)
    EndFunc ;==>_GUICtrlListView_GetSelectedIndices

    [/autoit]
    • Offizieller Beitrag

    Der Geschwindigkeitsunterschied ist ja heftig, so an die 190 mal schneller.
    Sollte mal jemand im Englischen Forum posten.

  • Ja, ja, die geliebten UDFs. Einer geht noch, weil man diese Funktion nicht wirklich braucht:

    Spoiler anzeigen
    [autoit]

    #include <GuiListView.au3>

    [/autoit] [autoit][/autoit] [autoit]

    $hGui = GUICreate('Listview-Test', 400, 600)
    $hListView = GUICtrlCreateListView('a|b|c|d', 5, 5, 390, 590, $LVS_SHOWSELALWAYS)
    For $i = 0 To 999
    $sItem = Random(1000, 9999, 1) & '|' & Random(1000, 9999, 1) & '|' & Random(1000, 9999, 1) & '|' & Random(1000, 9999, 1)
    GUICtrlCreateListViewItem($sItem, $hListView)
    Next
    GUISetState()

    [/autoit] [autoit][/autoit] [autoit]

    $hWndLV = GUICtrlGetHandle($hListView)
    _GUICtrlListView_SetItemSelected($hWndLV, -1, True)
    $T1 = 0
    $T2 = 0
    $T3 = 0
    $Loops = 10
    For $I = 1 To $Loops
    $aSelIndices1 = 0
    $iTimer = TimerInit()
    $aSelIndices1 = _GUICtrlListView_GetSelectedIndices($hListView, True) ; das Original
    $T1 += TimerDiff($iTimer)
    $aSelIndices2 = 0
    $iTimer = TimerInit()
    $aSelIndices2 = _GUICtrlListView_GetSelectedIndicesNew($hListView, True) ; die modifizierte Version (unten)
    $T2 += TimerDiff($iTimer)
    $aSelIndices3 = 0
    $iTimer = TimerInit()
    $aSelIndices3 = _GUICtrlListView_GetSelectedIndicesNewNew($hListView, True) ; die 2. modifizierte Version (unten)
    $T3 += TimerDiff($iTimer)
    Next
    ConsoleWrite('Original: ' & ($T1 / $Loops) & @CR)
    ConsoleWrite('Modifiziert: ' & ($T2 / $Loops) & @CR)
    ConsoleWrite('Modifiziert 2: ' & ($T3 / $Loops) & @CR)
    _ArrayDisplay($aSelIndices1, "Original")
    _ArrayDisplay($aSelIndices2, "Modifiziert")
    _ArrayDisplay($aSelIndices3, "Modifiziert 2")

    [/autoit] [autoit][/autoit] [autoit]

    Do
    Until GUIGetMsg() = -3

    [/autoit] [autoit][/autoit] [autoit]

    ; #FUNCTION# ====================================================================================================================
    ; Name...........: _GUICtrlListView_GetSelectedIndicesNew
    ; Description ...: Retrieve indices of selected item(s)
    ; Syntax.........: _GUICtrlListView_GetSelectedIndices($hWnd, $fArray = False)
    ; Parameters ....: $hWnd - Handle to the control
    ; $fArray - Return string or Array
    ; |True - Returns array
    ; |False - Returns pipe "|" delimited string
    ; Return values .: Success - Selected indices Based on $fArray:
    ; +Array - With the following format
    ; |[0] - Number of Items in array (n)
    ; |[1] - First item index
    ; |[2] - Second item index
    ; |[n] - Last item index
    ; |String - With the following format
    ; |"0|1|2|n"
    ; Failure - Based on $fArray
    ; |Array - With the following format
    ; |[0] - Number of Items in array (0)
    ; |String - Empty ("")
    ; Author ........: Gary Frost (gafrost)
    ; Modified.......:
    ; Remarks .......:
    ; Related .......:
    ; Link ..........:
    ; Example .......: Yes
    ; ===============================================================================================================================
    Func _GUICtrlListView_GetSelectedIndicesNew($hWnd, $fArray = False)
    If $Debug_LV Then __UDF_ValidateClassName($hWnd, $__LISTVIEWCONSTANT_ClassName)

    [/autoit] [autoit][/autoit] [autoit]

    Local $sIndices, $iRet, $iCount = _GUICtrlListView_GetItemCount($hWnd)
    For $iItem = 0 To $iCount
    If IsHWnd($hWnd) Then
    $iRet = _SendMessage($hWnd, $LVM_GETITEMSTATE, $iItem, $LVIS_SELECTED)
    Else
    $iRet = GUICtrlSendMsg($hWnd, $LVM_GETITEMSTATE, $iItem, $LVIS_SELECTED)
    EndIf
    If $iRet Then $sIndices &= $iItem & '|'
    Next
    If $fArray Then Return StringSplit(StringTrimRight($sIndices, 1), '|')
    Return StringTrimRight($sIndices, 1)
    EndFunc ;==>_GUICtrlListView_GetSelectedIndices

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    Func _GUICtrlListView_GetSelectedIndicesNewNew($hWnd, $fArray = False)
    If $Debug_LV Then __UDF_ValidateClassName($hWnd, $__LISTVIEWCONSTANT_ClassName)

    [/autoit] [autoit][/autoit] [autoit]

    Local $hGui, $idCtrl, $sIndices

    [/autoit] [autoit][/autoit] [autoit]

    If IsHWnd($hWnd) Then
    $idCtrl = _WinAPI_GetDlgCtrlID($hWnd)
    Else
    $idCtrl = $hWnd
    $hWnd = GUICtrlGetHandle($hWnd)
    EndIf
    $hGui = _WinAPI_GetAncestor($hWnd)

    [/autoit] [autoit][/autoit] [autoit]

    $sIndices = ControlListView($hGui, "", $idCtrl, "GetSelected", 1)

    [/autoit] [autoit][/autoit] [autoit]

    If $fArray Then Return StringSplit($sIndices, '|')
    Return $sIndices
    EndFunc ;==>_GUICtrlListView_GetSelectedIndices

    [/autoit]
    • Offizieller Beitrag

    Das wäre mal die Idee. UNterforum von Scripten mit optimierten UDF Funktionen.

    @Großvater, 1A Arbeit. :thumbup: