Про точность. Из всех методов измерения длительности - на моей тачке самый точный Stopwatch
Для измерения точного монотонного времени написал класс:
public static class Clock
{
public static double GetSeconds ();
}
Возвращает количество секунд прошедшее с момента старта программы (точнее с момента инициализации статического класса Clock, но он инициализируется в main).
Он имеет следующую реализацию
Под виндой:
private static class Windows_PerformanceCounter
{
[System.Runtime.InteropServices.DllImport("kernel32.dll")]
private static extern int QueryPerformanceFrequency (out long frequency);
[System.Runtime.InteropServices.DllImport("kernel32.dll")]
private static extern int QueryPerformanceCounter (out long counter);
private static readonly double scale, offset;
static Windows_PerformanceCounter ()
{
long frequency;
QueryPerformanceFrequency(out frequency);
if (frequency > 0)
{
scale = 1.0 / frequency;
long count;
QueryPerformanceCounter(out count);
offset = scale * count;
}
}
public static double GetSeconds ()
{
long count;
QueryPerformanceCounter(out count);
return scale * count - offset;
}
}
Под Линуксом:
private static class Unix_librt
{
private const int CLOCK_MONOTONIC = 1;
private struct Time
{
public uint seconds;
public uint nanoseconds;
}
[System.Runtime.InteropServices.DllImport("/lib/librt.so.1")]
private static extern int clock_gettime (int clockId, ref Time time);
private static double offset;
public static double GetSeconds ()
{
Time t = new Time();
clock_gettime(CLOCK_MONOTONIC, ref t);
return t.seconds + 0.000000001*t.nanoseconds - offset;
}
static Unix_librt ()
{
offset = GetSeconds();
}
}
Точность от 200 нс до 1400 нс в зависимости от компьютера (от часов в чиспете). 200 нс было на каком-то современном ксеонистом 16 ядерном серваке, а 1400 на каком-то старом компьютере времён Pentium 4.
Кстати под Линуксом System.DateTime.UtcNow имеет такую же высокую точность, но имеет недостаток -- не монотонен (зависит от перевода часов).