Pergunta sobre profiling, vb6, string, timer – Como obter o tempo decorrido em milissegundos

6

Como o desempenho da concatenação de strings é bastante fraco no VB6, estou testando várias implementações do StringBuilder. Para ver por quanto tempo eles estão rodando, eu atualmente uso o built-in

Timer

função que só me dá o número de segundos que se passaram depois da meia-noite.

Existe uma maneira (eu acho que importando uma função do sistema) para obter algo com precisão de milissegundos?

Sua resposta

8   a resposta
0

lasse embora). Este código permite que você mantenha até seis temporizadores, com alta precisão:

Option Explicit

Private Declare Function QueryPerformanceFrequency Lib "kernel32" (lpFrequency As Currency) As Long
Private Declare Function QueryPerformanceCounter Lib "kernel32" (lpPerformanceCount As Currency) As Long

Private cFrequency As Currency
Private cCounters(0 To 5) As Currency

Public Sub StartCounter(Optional lCounterIndex As Long)
    QueryPerformanceFrequency cFrequency
    QueryPerformanceCounter cCounters(lCounterIndex)
End Sub

Public Function GetCounter(Optional lCounterIndex As Long) As Double
    Dim cCount As Currency

    QueryPerformanceFrequency cFrequency
    QueryPerformanceCounter cCount
    GetCounter = Format$((cCount - cCounters(lCounterIndex) - CCur(0.0008)) / cFrequency, "0.000000000")
End Function

Public Function Scientific(ByVal dValue As Double) As String
    Dim lMultiplier As Long
    Dim vNames As Variant

    lMultiplier = 5
    vNames = Array("peta", "tera", "giga", "mega", "kilo", "", "milli", "micro", "nano", "pico", "femto")
    If Abs(dValue) < 1 Then
        While Abs(dValue) < 1
            dValue = dValue * 1000
            lMultiplier = lMultiplier + 1
        Wend
    ElseIf Abs(dValue) >= 1000 Then
        While Abs(dValue) >= 1000
            dValue = dValue / 1000
            lMultiplier = lMultiplier - 1
        Wend
    End If

    Scientific = Format$(dValue, "0.000") & " " & vNames(lMultiplier)
End Function
7

Coloque o seguinte código em uma classe Stopwatch:

Option Explicit

Private Declare Function QueryPerformanceCounter Lib "Kernel32" (X As Currency) As Boolean
Private Declare Function QueryPerformanceFrequency Lib "Kernel32" (X As Currency) As Boolean

Private m_startTime As Currency
Private m_freq As Currency
Private m_overhead As Currency

Public Sub start()
    QueryPerformanceCounter m_startTime
End Sub

Public Function ElapsedSeconds() As Double
    Dim currentTime As Currency
    QueryPerformanceCounter currentTime
    ElapsedSeconds = (currentTime - m_startTime - m_overhead) / m_freq
End Function

Public Function ElapsedMilliseconds() As Double
    ElapsedMilliseconds = ElapsedSeconds * 1000
End Function

Private Sub Class_Initialize()
    QueryPerformanceFrequency m_freq
    Dim ctr1 As Currency
    Dim ctr2 As Currency
    QueryPerformanceCounter ctr1
    QueryPerformanceCounter ctr2
    m_overhead = ctr2 - ctr1
End Sub

Você pode usá-lo da seguinte maneira:

Dim sw as StopWatch
sw = New StopWatch
sw.Start

' Code you want to time

Debug.Print "Code took " & sw.ElapsedMilliseconds " ms"
Isso também é muito bom para coletar algumas estatísticas de depuração ou implementar um registrador de desempenho. RobertB
-2

: Diagnostics :: Stopwatch

Imports System.Diagnostics

Dim sw As New Stopwatch()
sw.Start()
// do something
LOG("Elapsed " + sw.ElapsedMilliseconds + " ms")
Este é o código .NET, ele especificamente disse VB6 (que foi o último lançamento antes do .NET 1.0 ser lançado) Matthew Scharley
Desculpe, minha culpa. Em seguida, o GetTickCount é o caminho a percorrer no VB6, pois é a alternativa para o objeto clock_t em C / C ++ Ezekiel Rage
O .NET StopWatch usa QueryPerformanceCounter / QueryPerformanceFrequency em segundo plano, quando possível (você pode descobrir se ele é usado examinando a propriedade IsHighResolution do StopWatch) Patrick McDonald
12

Sim, você pode usar a API do Win32:

DWORD WINAPI GetTickCount(void);

Para importá-lo no VB6, declare-o assim:

Private Declare Function GetTickCount Lib "kernel32" () As Long

Chame antes da operação e depois calcule a diferença no tempo passado.

GetTickCount é bom o suficiente para a maioria dos propósitos, desde que você esteja ciente de suas limitações, tente o código emsupport.microsoft.com/kb/172338 no entanto, para se certificar de que a precisão de 10ms é o melhor que você vai conseguir em qualquer sistema Windows Patrick McDonald
O artigo de FYI Raymond Chen (Precisão não é o mesmo que precisão) agora pode ser encontrado aqui:devblogs.microsoft.com/oldnewthing/20050902-00/?p=34333 Patrick McDonald
GetTickCount só tem 10ms de precisão, se você precisar de mais precisão que isso você deve usar QueryPerformanceCounter Patrick McDonald
msdn não diz nada sobre 10ms, mas diz: "A resolução é limitada à resolução do timer do sistema. Esse valor também é afetado por ajustes feitos pela função GetSystemTimeAdjustment." então talvez 10ms é para sua máquina específica? justadreamer
1

onde ele está entrevistando alguns engenheiros em potencial.

Ele pede que eles determinem o volume de uma lâmpada. O candidato A mede e usa a fórmula para o volume de uma esfera, e outra fórmula para o volume do pescoço, e assim por diante. O candidato B enche-o com água e despeja-o num copo de medição. Quem você acha que conseguiu o emprego?

Execute-o 1000 vezes e observe seu relógio antes e depois. Segundos = milissegundos.

1

QueryPerformanceCounter: Para obter a contagem no início e no final do evento.QueryPerformanceFrequency: Para obter o número de tiques por segundo.

Estes usam LARGE_INTEGER para representar números de 64 bits.

Código VB6 neste artigo da MSDN KnowledgeBase:support.microsoft.com/kb/172338 MarkJ
2

suas rotinas de um loop com iterações suficientes para lhe dar uma diferença de tempo mensurável.

Perguntas relacionadas