ID do artigo: 172338 - Última revisão: sábado, 20 de janeiro de 2007 - Revisão: 3.3

Como usar QueryPerformanceCounter para código de tempo

Dica do SistemaEste artigo aplica-se a um sistema operativo diferente do que está a utilizar. Foi desactivado o conteúdo do artigo, que pode não ser relevante para si.

Nesta página

Expandir tudo | Recolher tudo

Sumário

Quando o código para identificar afunilamentos de desempenho de tempo, você deseja usar o timer de resolução mais alto que o sistema tem a oferecer. Este artigo descreve como usar a função de QueryPerformanceCounter para código de aplicativo de tempo.

Mais Informações

Diversos timers de precisão diferente são oferecidos pelo sistema operacional:
Function                 Units                      Resolution
---------------------------------------------------------------------------
Now, Time, Timer         seconds                    1 second
GetTickCount             milliseconds               approx. 10 ms
TimeGetTime              milliseconds               approx. 10 ms
QueryPerformanceCounter  QueryPerformanceFrequency  same
				
se seu sistema oferece suporte a um contador de alta resolução, você pode usar QueryPerformanceCounter e QueryPerformanceFrequency fazer intervalos de alta resolução.

O código de exemplo a seguir compara os vários contadores:

AVISO: QUALQUER USO QUE VOCÊ O CÓDIGO FORNECIDO NESTE ARTIGO É DE SUA RESPONSABILIDADE. A Microsoft fornece esse código "como estão" sem garantia de qualquer tipo, expressa ou implícita, inclusive mas não limitada às garantias implícitas de comercialização e/ou adequação a uma finalidade específica.

Procedimentos passo a passo

  1. Insira o código a seguir em um módulo. Se você inserir em uma classe, formulário ou módulo de relatório, verifique as declarações particular.
           Option Explicit
    
          Declare Function QueryPerformanceCounter Lib "Kernel32" _
                                     (X As Currency) As Boolean
          Declare Function QueryPerformanceFrequency Lib "Kernel32" _
                                     (X As Currency) As Boolean
          Declare Function GetTickCount Lib "Kernel32" () As Long
          Declare Function timeGetTime Lib "winmm.dll" () As Long
    
          Sub Test_Timers()
          Dim Ctr1 As Currency, Ctr2 As Currency, Freq As Currency
          Dim Count1 As Long, Count2 As Long, Loops As Long
          '
          ' Time QueryPerformanceCounter
          '
            If QueryPerformanceCounter(Ctr1) Then
              QueryPerformanceCounter Ctr2
              Debug.Print "Start Value: "; Format$(Ctr1, "0.0000")
              Debug.Print "End Value: "; Format$(Ctr2, "0.0000")
              QueryPerformanceFrequency Freq
              Debug.Print "QueryPerformanceCounter minimum resolution: 1/" & _
                          Freq * 10000; " sec"
              Debug.Print "API Overhead: "; (Ctr2 - Ctr1) / Freq; "seconds"
            Else
              Debug.Print "High-resolution counter not supported."
            End If
          '
          ' Time GetTickCount
          '
            Debug.Print
            Loops = 0
            Count1 = GetTickCount()
            Do
              Count2 = GetTickCount()
              Loops = Loops + 1
            Loop Until Count1 <> Count2
            Debug.Print "GetTickCount minimum resolution: "; _
                        (Count2 - Count1); "ms"
            Debug.Print "Took"; Loops; "loops"
          '
          ' Time timeGetTime
          '
            Debug.Print
            Loops = 0
            Count1 = timeGetTime()
            Do
              Count2 = timeGetTime()
              Loops = Loops + 1
            Loop Until Count1 <> Count2
            Debug.Print "timeGetTime minimum resolution: "; _
                        (Count2 - Count1); "ms"
            Debug.Print "Took"; Loops; "loops"
          End Sub
    						
  2. Execute a função da janela imediata/Debug. A saída deverá ser exibida semelhante à seguinte:
    Inicia valor: 3516284.3498
    End valor: 3516284.3521
    Resolução mínima de QueryPerformanceCounter: 1/1193182 s
    Despesas de API: 1.92761875388667E - 05 segundos

    Resolução mínima de ObterContagemMarcaEscala: 10 ms
    Levou 650 loops

    resolução mínima timeGetTime: 10 ms
    Levou 1565 loops
Várias instruções executar antes que uma alteração de registro ou ObterContagemMarcaEscala timeGetTime. O número real de loops irá variar dependendo as tarefas de plano de fundo que o sistema operacional está sendo executado.

Por outro lado, QueryPerformanceCounter altera o valor entre chamadas de API sucessivas, indicando sua utilidade em tempo de alta resolução. Nesse caso é a resolução na ordem de um microssegundo. Porque a resolução é dependente de sistema, não há nenhum unidades padrão que ele mede. Você precisa dividir a diferença por QueryPerformanceFrequency para determinar que o número de segundos decorridos. No caso acima, a sobrecarga para apenas chamar a API é sobre 19 microssegundos. Isso teria que ser subtraído quando outro código o tempo da seguinte maneira:
   Private Sub Time_Addition()
   Dim Ctr1 As Currency, Ctr2 As Currency, Freq As Currency
   Dim Overhead As Currency, A As Long, I As Long
     QueryPerformanceFrequency Freq
     QueryPerformanceCounter Ctr1
     QueryPerformanceCounter Ctr2
     Overhead = Ctr2 - Ctr1        ' determine API overhead
     QueryPerformanceCounter Ctr1  ' time loop
     For I = 1 To 100
       A = A + I
     Next I
     QueryPerformanceCounter Ctr2
     Debug.Print "("; Ctr1; "-"; Ctr2; "-"; Overhead; ") /"; Freq
     Debug.Print "100 additions took";
     Debug.Print (Ctr2 - Ctr1 - Overhead) / Freq; "seconds"
   End Sub
				
saída de exemplo:
(3630876.6256 3630876.6388-0.0013) / 119.3182
adições de 100 levaram 9.97333181358753E - 05 segundos
Observação: Como moeda variáveis são usadas, os valores retornados são vezes 10000 menores do que os contadores reais. Como o cálculo do segundos envolve uma operação de divisão, esse fator é cancelada check-out.

Referências

Microsoft Developer Network; tópicos: timeGetTime ObterContagemMarcaEscala QueryPerformanceCounter QueryPerformanceFrequency

A informação contida neste artigo aplica-se a:
  • Microsoft Excel 2000 Standard Edition
  • Microsoft Visual Basic 5.0 Learning Edition
  • Microsoft Visual Basic 6.0 Learning Edition
  • Microsoft Visual Basic 5.0 Professional Edition
  • Microsoft Visual Basic 6.0 Professional Edition
  • Microsoft Visual Basic 5.0 Enterprise Edition
  • Microsoft Visual Basic Enterprise Edition for Windows 6.0
  • Microsoft Visual Basic Control Creation Edition
  • Microsoft Visual Basic 4.0 Standard Edition
  • Microsoft Visual Basic 4.0 Professional Edition
  • Microsoft Visual Basic 4.0 de 32 Bits Enterprise Edition
  • Microsoft Access 2002 Standard Edition
  • Microsoft Access 2000 Standard Edition
  • Microsoft Access 97 Standard Edition
  • Microsoft Access 95 Standard Edition
  • Microsoft Excel 2002 Standard Edition
  • Microsoft Excel 97 Standard Edition
  • Microsoft Excel 95 Standard Edition
  • Microsoft Word 2002 Standard Edition
  • Microsoft Word 2000 Standard Edition
  • Microsoft Word 97 Standard Edition
Palavras-chave: 
kbmt kbhowto kbprogramming KB172338 KbMtpt
Tradução automáticaTradução automática
IMPORTANTE: Este artigo foi traduzido por um sistema de tradução automática (também designado por Machine Translation ou MT), não tendo sido portanto traduzido ou revisto por pessoas. A Microsoft possui artigos traduzidos por aplicações (MT) e artigos traduzidos por tradutores profissionais, com o objetivo de oferecer em português a totalidade dos artigos existentes na base de dados de suporte. No entanto, a tradução automática não é sempre perfeita, podendo conter erros de vocabulário, sintaxe ou gramática. A Microsoft não é responsável por incoerências, erros ou prejuízos ocorridos em decorrência da utilização dos artigos MT por parte dos nossos clientes. A Microsoft realiza atualizações freqüentes ao software de tradução automática (MT). Obrigado.
Clique aqui para ver a versão em Inglês deste artigo: 172338  (http://support.microsoft.com/kb/172338/en-us/ )