ナノ秒という単位の精度で経過時間を取得するために使用するのが
QueryPerformanceCounterとQueryPerformanceFrequencyです。
Sample
using System;
using System.Runtime.InteropServices;
public class TraceTime
{
#region
[DllImport("kernel32.dll")]
extern static int QueryPerformanceCounter(ref long x);
[DllImport("kernel32.dll")]
extern static int QueryPerformanceFrequency(ref long x);
#endregion
#region フィールド
long st;
long end;
long frq;
#endregion
public TraceTime()
{
st = 0;
end = 0;
QueryPerformanceFrequency(ref frq);
}
public void Start()
{
QueryPerformanceCounter(ref st);
}
public void Stop()
{
QueryPerformanceCounter(ref end);
}
public double NowResult()
{
long now = 0;
QueryPerformanceCounter(ref now);
return (double)(now - st) / frq;
}
public double Result()
{
return (double)(end - st) / frq;
}
}Test
1秒Sleepさせて経過時間を取得する処理を10回繰り返しています。class Program
{
static void Main(string[] args)
{
TraceTime traceTime = new TraceTime();
int loop = 10;
double[] ttm = new double[loop];
for (int i = 0; i < loop; i++)
{
traceTime.Start();
System.Threading.Thread.Sleep(1000);
ttm[i] = traceTime.NowResult();
}
Console.WriteLine("Average:" + ttm.Average());
Console.WriteLine("Min:" + ttm.Min());
Console.WriteLine("Max:" + ttm.Max());
Console.WriteLine("Error Range:" + (ttm.Max() - ttm.Min()));
Console.ReadLine();
}
}Result
Average:1.00004832318074
Min:0.999835104740966
Max:1.0001991174856
Error Range:0.00036012744636488
重要なのは以下の部分だけです。
[DllImport("kernel32.dll")]
extern static int QueryPerformanceCounter(ref long x);
[DllImport("kernel32.dll")]
extern static int QueryPerformanceFrequency(ref long x);
後は使いやすいように追加/修正するだけです。と言っても、値のチェックを入れるぐらいで他は大体同じになるのですが。
FYA
以下のサイトには例外のthrowまで書かれたものがありましたので参考に。わんくまライブラリ Wankuma.Interop.InteropQueryPerformanceCounterクラス Version2





0 Comments:
コメントを投稿