Correspondência otimizada para RAM não consumo de CPU

2

Estou procurando maneiras diferentes de obter o número da linha de uma célula idêntica em outro intervalo.

Uma das maneiras mais rápidas é usar a função Match. Quando executado em dois intervalos muito grandes (acima de 500.000 linhas cada), ele será (por padrão) executado em paralelo em toda a CPU e, com uma boa CPU, será muito rápido. Quando a CPU é fraca ou tem poucos núcleos (ou não suporta multi-threading), no entanto, isso pode levar muito tempo. Não usa quase nenhuma RAM.

Existe um tipo de correspondência que usa muita RAM, mas pouca CPU? Isso seria muito útil para computadores que possuem muito memória RAM, mas uma CPU mais antiga.

    
por wizlog 27.09.2017 / 21:58

1 resposta

2

Eu conheço quatro maneiras de pesquisar, mas acho que o fator determinante sempre será a CPU

O teste:

- out of the max of 1048576
- find cell        A1048573

Nada chega perto do 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%

Código:

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

Mais detalhes aqui e aqui

    
por 28.09.2017 / 22:05