Сопоставление оптимизировано для потребления оперативной памяти, а не процессора

Сопоставление оптимизировано для потребления оперативной памяти, а не процессора

Я ищу разные способы получить номер строки идентичной ячейки в другом диапазоне.

Один из самых быстрых способов — использовать функцию Match. При запуске на двух очень больших диапазонах (более 500 000 строк каждый) она (по умолчанию) будет работать параллельно на CPU и, при наличии хорошего CPU, будет работать очень быстро. Однако, если CPU слабый или имеет мало ядер (или не поддерживает многопоточность), это может занять очень много времени. Она почти не использует RAM.

Есть ли тип соответствия, который использует много оперативной памяти, но очень мало процессора? Это было бы очень полезно для компьютеров, у которых много оперативной памяти, но старый процессор.

решение1

Я знаю 4 способа поиска, но я думаю, что определяющим фактором всегда будет процессор.

Тест:

- out of the max of 1048576
- find cell        A1048573

Ничто не сравнится с Match


Time -   LookupAppMatch(): 0.047 sec      CPU usage 1%
Time -   LookupAppMatch(): 0.031 sec      CPU usage 0%
Time -   LookupAppMatch(): 0.031 sec      CPU usage 1%

Time -    LookupWSMatch(): 0.047 sec      CPU usage 1%
Time -    LookupWSMatch(): 0.063 sec      CPU usage 0%
Time -    LookupWSMatch(): 0.047 sec      CPU usage 0%

Time -       LookupFind(): 0.672 sec      CPU usage 8%
Time -       LookupFind(): 0.625 sec      CPU usage 5%
Time -       LookupFind(): 0.625 sec      CPU usage 7%

Time -    LookupForLoop(): 0.297 sec      CPU usage 5%
Time -    LookupForLoop(): 0.297 sec      CPU usage 3%
Time -    LookupForLoop(): 0.297 sec      CPU usage 3%

Time - LookupAutoFilter(): 0.672 sec      CPU usage 7%
Time - LookupAutoFilter(): 0.359 sec      CPU usage 5%
Time - LookupAutoFilter(): 0.375 sec      CPU usage 7%

Код:


Option Explicit

Private Const FND = "A1048573"
Private t As Double

Public Sub SetupData()
    Sheet1.Columns(1).Formula = "=Address(Row(), Column(), 4)"
End Sub

Public Sub LookupAppMatch()
    t = Timer
    Sheet1.Cells(1, 2) = Application.Match(FND, Sheet1.Columns(1), 0)
    Debug.Print "Time -   LookupAppMatch(): " & Format(Timer - t, "0.000") & " sec"
End Sub

Public Sub LookupWSMatch()
    t = Timer
    Sheet1.Cells(2, 2) = WorksheetFunction.Match(FND, Sheet1.Columns(1), 0)
    Debug.Print "Time -    LookupWSMatch(): " & Format(Timer - t, "0.000") & " sec"
End Sub

Public Sub LookupFind()
    t = Timer
    Sheet1.Cells(3, 2) = Sheet1.Columns(1).Find(What:=FND, LookIn:=xlValues, LookAt:=xlWhole, MatchCase:=True).Row
    Debug.Print "Time -       LookupFind(): " & Format(Timer - t, "0.000") & " sec"
End Sub

Public Sub LookupForLoop()
    Dim ur As Variant, r As Long
    t = Timer
    ur = Sheet1.Columns(1)
    For r = 1 To UBound(ur)
        If ur(r, 1) = FND Then Exit For
    Next
    Sheet1.Cells(4, 2) = r
    Debug.Print "Time -    LookupForLoop(): " & Format(Timer - t, "0.000") & " sec"
End Sub

Public Sub LookupAutoFilter()
    t = Timer
    Application.ScreenUpdating = False
    With Sheet1.Columns(1)
        .AutoFilter Field:=1, Criteria1:=FND
        Sheet1.Cells(5, 2) = .Rows.Count - .SpecialCells(xlVisible).Cells.CountLarge - 1
        .AutoFilter
    End With
    Application.ScreenUpdating = True
    Debug.Print "Time - LookupAutoFilter(): " & Format(Timer - t, "0.000") & " sec"
End Sub

Подробнеездесьиздесь

Связанный контент