방법: 고해상도 타이머 사용
업데이트: 2007년 11월
일부 장치에서는 고해상도 타이머를 지원합니다. 이 타이머가 있으면 해상도가 1밀리초인 TickCount 속성을 사용할 때보다 시간을 정확하게 측정할 수 있습니다. 정확한 시간 측정이 중요한 응용 프로그램에서 고해상도 타이머를 사용하면 최상의 결과를 얻을 수 있습니다. 예를 들어, 일부 Direct3D 응용 프로그램은 애니메이션이 고해상도 타이머를 기반으로 하는 경우에 보다 부드럽게 표시됩니다. 응용 프로그램에서 이 타이머를 사용하여 코드의 섹션이나 메서드를 실행하는 데 필요한 시간을 확인할 수도 있습니다.
예제
이 코드 예제에서는 Windows CE의 관리 코드에서 고해상도 타이머를 손쉽게 사용할 수 있도록 해 주는 클래스를 제공합니다. 이 예제에는 다음과 같은 기능이 포함되어 있습니다.
Windows CE에서 네이티브 메서드에 대한 플랫폼 호출 선언
고해상도 카운터의 빈도를 가져오는 데 사용하는 속성
고해상도 카운터의 값을 가져오는 데 사용하는 속성
QueryPerformanceCounter 함수가 지원되지 않거나 에뮬레이트되는 경우 TickCount 속성을 대신 지원하는 구현
고해상도 카운터를 사용하여 작업 시간을 측정하는 방법을 보여 주는 예제
Public Class HiResTimer
Private isPerfCounterSupported As Boolean = False
Private timerFrequency As Int64 = 0
' Windows CE native library with QueryPerformanceCounter().
Private Const [lib] As String = "coredll.dll"
Public Declare Function QueryPerformanceCounter Lib "Coredll.dll" _
(ByRef count As Int64) As Integer
Public Declare Function QueryPerformanceFrequency Lib "Coredll.dll" _
(ByRef timerFrequency As Int64) As Integer
Public Sub New()
' Query the high-resolution timer only if it is supported.
' A returned frequency of 1000 typically indicates that it is not
' supported and is emulated by the OS using the same value that is
' returned by Environment.TickCount.
' A return value of 0 indicates that the performance counter is
' not supported.
Dim returnVal As Integer = QueryPerformanceFrequency(timerFrequency)
If returnVal <> 0 AndAlso timerFrequency <> 1000 Then
' The performance counter is supported.
isPerfCounterSupported = True
Else
' The performance counter is not supported. Use
' Environment.TickCount instead.
timerFrequency = 1000
End If
End Sub
Public ReadOnly Property Frequency() As Int64
Get
Return timerFrequency
End Get
End Property
Public ReadOnly Property Value() As Int64
Get
Dim tickCount As Int64 = 0
If isPerfCounterSupported Then
' Get the value here if the counter is supported.
QueryPerformanceCounter(tickCount)
Return tickCount
Else
' Otherwise, use Environment.TickCount
Return CType(Environment.TickCount, Int64)
End If
End Get
End Property
Shared Sub Main()
Dim timer As New HiResTimer()
' This example shows how to use the high-resolution counter to
' time an operation.
' Get counter value before the operation starts.
Dim counterAtStart As Int64 = timer.Value
' Perform an operation that takes a measureable amount of time.
Dim count As Integer
For count = 0 To 9999
count += 1
count -= 1
Next count
' Get counter value after the operation ends.
Dim counterAtEnd As Int64 = timer.Value
' Get time elapsed in tenths of milliseconds
Dim timeElapsedInTicks As Int64 = counterAtEnd - counterAtStart
Dim timeElapseInTenthsOfMilliseconds As Int64 = timeElapsedInTicks * 10000 / timer.Frequency
MessageBox.Show("Time Spent in operation (tenths of ms) " + timeElapseInTenthsOfMilliseconds.ToString + vbLf + "Counter Value At Start: " + counterAtStart.ToString + vbLf + "Counter Value At End : " + counterAtEnd.ToString + vbLf + "Counter Frequency : " + timer.Frequency.ToString)
End Sub
End Class
public class HiResTimer
{
private bool isPerfCounterSupported = false;
private Int64 frequency = 0;
// Windows CE native library with QueryPerformanceCounter().
private const string lib = "coredll.dll";
[DllImport(lib)]
private static extern int QueryPerformanceCounter(ref Int64 count);
[DllImport(lib)]
private static extern int QueryPerformanceFrequency(ref Int64 frequency);
public HiResTimer()
{
// Query the high-resolution timer only if it is supported.
// A returned frequency of 1000 typically indicates that it is not
// supported and is emulated by the OS using the same value that is
// returned by Environment.TickCount.
// A return value of 0 indicates that the performance counter is
// not supported.
int returnVal = QueryPerformanceFrequency(ref frequency);
if (returnVal != 0 && frequency != 1000)
{
// The performance counter is supported.
isPerfCounterSupported = true;
}
else
{
// The performance counter is not supported. Use
// Environment.TickCount instead.
frequency = 1000;
}
}
public Int64 Frequency
{
get
{
return frequency;
}
}
public Int64 Value
{
get
{
Int64 tickCount = 0;
if (isPerfCounterSupported)
{
// Get the value here if the counter is supported.
QueryPerformanceCounter(ref tickCount);
return tickCount;
}
else
{
// Otherwise, use Environment.TickCount.
return (Int64)Environment.TickCount;
}
}
}
static void Main()
{
HiResTimer timer = new HiResTimer();
// This example shows how to use the high-resolution counter to
// time an operation.
// Get counter value before the operation starts.
Int64 counterAtStart = timer.Value;
// Perform an operation that takes a measureable amount of time.
for (int count = 0; count < 10000; count++)
{
count++;
count--;
}
// Get counter value when the operation ends.
Int64 counterAtEnd = timer.Value;
// Get time elapsed in tenths of a millisecond.
Int64 timeElapsedInTicks = counterAtEnd - counterAtStart;
Int64 timeElapseInTenthsOfMilliseconds =
(timeElapsedInTicks * 10000) / timer.Frequency;
MessageBox.Show("Time Spent in operation (tenths of ms) "
+ timeElapseInTenthsOfMilliseconds +
"\nCounter Value At Start: " + counterAtStart +
"\nCounter Value At End : " + counterAtEnd +
"\nCounter Frequency : " + timer.Frequency);
}
}
코드 컴파일
이 예제에는 다음과 같은 네임스페이스에 대한 참조가 필요합니다.