針對 RAM 而非 CPU 消耗進行最佳化的匹配

針對 RAM 而非 CPU 消耗進行最佳化的匹配

我正在尋找不同的方法來獲取另一個範圍中相同單元格的行號。

最快的方法之一是使用 Match 函數。當運行兩個非常大的範圍(每個範圍超過 500,000 行)時,它將(預設)在 CPU 上並行運行,並且如果 CPU 性能良好,運行速度會非常快。然而,當 CPU 較弱或核心數很少(或不支援多執行緒)時,這可能需要很長時間。它幾乎不使用 RAM。

是否有比賽類型使用大量 RAM 但很少使用 CPU?這對於擁有大量記憶體但 CPU 較舊的電腦非常有用。

答案1

我知道有 4 種搜尋方法,但我認為決定因素始終是 CPU

考試:

- 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

更多細節這裡這裡

相關內容