Что нового

Увеличение скорости поиска в ListView

ra4o

AutoIT Гуру
Сообщения
1,165
Репутация
247
? n : n В справке ничего не видел такого, или плохо смотрел. Подскажите где об этом прочесть можно.
Есть в англоязычной справке
Сообщение автоматически объединено:

Переменная $ia примет значение "0" при условии, что $bReverse = True и значение "1" , если $bReverse = False


 
  • Like
Реакции: Norm

xXx

╚{■_■}╗
Меценат
Сообщения
248
Репутация
95
... 120, False, True , то по идее должно вернуться -1...
А в переменных $sFindText , $iItems, $iSubItems что при этом?
... не первый раз встречаю такую конструкцию...
Читайте Ternary
Код:
; Такая запись:
$vVar_Max = ($vVar_1 > $vVar_2) ? $vVar_1 : $vVar_2

; аналогична нижеследующей:
If $vVar_1 > $vVar_2 Then
    $vVar_Max = $vVar_1
Else
   $vVar_Max = $vVar_2
EndIf
 
Последнее редактирование:
  • Like
Реакции: Norm

xXx

╚{■_■}╗
Меценат
Сообщения
248
Репутация
95
Последнее редактирование:

CreatoR

Must AutoIt!
Команда форума
Администратор
Сообщения
8,673
Репутация
2,486
Есть ли у Вас какой-то пример с этим?
Как то так (с выводом сравнения скорости):

Код:
#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#include <GUIListView.au3>

Global Enum $iLVCol_Index, $iLVCol_Item0, $iLVCol_Item1, $iLVCol_Item2, $iLVCol_Item3, $iLVCol_Item4, _
    $iLVCol_Total
Global $aLVItems[1][$iLVCol_Total]

$hGUI = GUICreate('_LV_FindInText', 300, 200)

$iLV = GUICtrlCreateListView('Col1|Col2|Col3|Col4|Col5', 20, 20, 260, 160)

For $i = 1 To 500
    $iItem = _LV_AddItem($iLV, 'Item' & $i)
    
    For $iSubItem = $iLVCol_Item0 To $iLVCol_Item4
        _LV_AddSubItem($iLV, $iItem, 'SubItem' & $i & ',' & $iSubItem, $iSubItem)
    Next
Next

GUISetState(@SW_SHOW, $hGUI)

$sText = 'SubItem405,3'
$iStart = 200
$bWrapOK = True
$bReverse = False

_SpeedTest('_Test_LV_FindInText')
_SpeedTest('_Test_GUICtrlListView_FindInText')

While 1
    Switch GUIGetMsg()
        Case $GUI_EVENT_CLOSE
            Exit
    EndSwitch
WEnd

Func _Test_LV_FindInText()
    Return _LV_FindInText($iLV, $sText, $iStart, $bWrapOK, $bReverse)
EndFunc

Func _Test_GUICtrlListView_FindInText()
    Return _GUICtrlListView_FindInText($iLV, $sText, $iStart, $bWrapOK, $bReverse)
EndFunc

Func _SpeedTest($sTestFunc, $sTitle = 'Testing', $iRepeat_Test = 5)
    Local $aTests[$iRepeat_Test + 1] = [$iRepeat_Test]
    Local $iTotal_Tests = 0
    
    ConsoleWrite(StringFormat('+ Tests for "Func %s" (%s) started...\n=--------------------=\n', $sTestFunc, $sTitle))
    
    Local $iDuration_Timer = TimerInit()
    
    For $x = 1 To $iRepeat_Test
        $iTimer = TimerInit()
        
        ;=== CODE TEST ====
        Call($sTestFunc)
        ;=== CODE TEST ===
        
        $aTests[$x] = Round(TimerDiff($iTimer), 3)
        $iTotal_Tests += $aTests[$x]
        ConsoleWrite(StringFormat('- Test #%i: %.2f ms\n', $x, $aTests[$x]))
    Next
    
    Local $iAverage = Round($iTotal_Tests / $iRepeat_Test, 3)
    ConsoleWrite(StringFormat('======================\n! Tests average: %.2f ms\n+ Test Duration: %.2f ms\n\n', $iAverage, TimerDiff($iDuration_Timer)))
EndFunc

Func _LV_AddItem($hWnd, $sText)
    $aLVItems[0][0] += 1
    ReDim $aLVItems[$aLVItems[0][0] + 1][$iLVCol_Total + 1]
    
    $aLVItems[$aLVItems[0][0]][$iLVCol_Index] = _GUICtrlListView_AddItem($hWnd, $sText)
    $aLVItems[$aLVItems[0][0]][$iLVCol_Item0] = $sText
    
    Return $aLVItems[$aLVItems[0][0]][$iLVCol_Index]
EndFunc

Func _LV_AddSubItem($hWnd, $iIndex, $sText, $iSubItem)
    _GUICtrlListView_AddSubItem($hWnd, $iIndex, $sText, $iSubItem)
    
    For $i = 1 To $aLVItems[0][0]
        If $aLVItems[$i][$iLVCol_Index] = $iIndex Then
            $aLVItems[$i][$iSubItem + 1] = $sText
        EndIf
    Next
EndFunc

Func _LV_FindInText($hWnd, $sText, $iStart = -1, $bWrapOK = True, $bReverse = False)
    Local $i_Start = ($iStart <= -1 ? 0 : $iStart + 1)
    Local $i_End = $aLVItems[0][0]
    Local $iStep = 1, $iFound = -1
    
    If $bReverse Then
        $i_Start = ($iStart <= -1 ? $aLVItems[0][0] : $iStart)
        $i_End = 0
        $iStep = -1
    EndIf
    
    While 1
        For $iIndex = $i_Start To $i_End Step $iStep
            If $iStart >= 0 And $iIndex - 1 = $iStart Then
                ContinueLoop
            EndIf
            
            For $iSubItem = $iLVCol_Item0 To $iLVCol_Item4
                If $aLVItems[$iIndex][$iSubItem] = $sText Then
                    Return $iIndex - 1
                EndIf
            Next
        Next
        
        If $bWrapOK Then
            $bWrapOK = False
            $i_Start = 0
            $i_End = ($bReverse ? $aLVItems[0][0] : $iStart + 1)
            $iStep = 1
            ContinueLoop
        EndIf
        
        Return -1
    WEnd
EndFunc
 
  • Like
Реакции: Norm
Автор
N

Norm

Продвинутый
Сообщения
291
Репутация
76
нужно просто создать обёртки (Wrapper)
Я думал, что это то, чего я ещё не знаю, а это просто такое "название" для этого.
Извините что заставил Вас пример для этого делать.:sad:
Очень хорошая альтернатива, для больших таблиц.

Для Вас конечно я Америку не открою , но для других это может быть полезным.
Ваш вариант поиска можно сделать ещё быстрее. (но при условии)
Я у себя именно так и сделал (для своей непомерно большой таблицы).
Если использовать для создания таблицы нативные функции, то и массив может иметь только два столбца.
В первом ID-Control от Item, а во втором вся строка с Items.
В итоге двойное ускорение при создании таблицы и поиск в массиве ещё быстрее, к которому (при желании)
можно ещё и "регулярный" поиск прикрутить или поиск соединяющий две/несколько ячеек в одной строке.
И самое главное уже не важно как отсортирована таблица. За этим тоже уже следить не нужно.

Но как я и говорил для маленьких или средних таблиц, поиск напрямую стал теперь более привлекательным.
Конечно поиск в массиве в сто раз быстрее будет, но лично для меня нет нужды создавать массив, если поиск с новой функцией не более 1 сек.
Здесь я ещё раз хотел бы поблагодарить xXx за помощь в доведении функции до конечного состояния.:yes:
 
Последнее редактирование:

CreatoR

Must AutoIt!
Команда форума
Администратор
Сообщения
8,673
Репутация
2,486
Если использовать для создания таблицы нативные функции, то и массив может иметь только два столбца
И при не нативных тоже можно, я просто показал более наглядно.

нет нужды создавать массив, если поиск с новой функцией не более 1 сек
Я всегда за то, чтобы при возможности оптимизировать код.
Я бы вообще передал библиотеку GUIListView с использованием виртуального списка.
 
Верх