【C#获取高精度时间】

在C#中,有几种方法可以获取高精度时间(高分辨率时间戳),适用于性能测量、计时等需要高精度的场景。以下是几种常用方法:

1. 使用 Stopwatch 类(推荐)

Stopwatch 类提供了最高精度的时间测量,适用于测量时间间隔。

csharp 复制代码
using System;
using System.Diagnostics;

class Program
{
    static void Main()
    {
        // 创建Stopwatch实例
        Stopwatch stopwatch = new Stopwatch();
        
        // 开始计时
        stopwatch.Start();
        
        // 执行一些操作
        for (int i = 0; i < 1000000; i++)
        {
            var x = Math.Sqrt(i);
        }
        
        // 停止计时
        stopwatch.Stop();
        
        // 获取经过的时间
        Console.WriteLine($"Elapsed Time: {stopwatch.Elapsed}");
        Console.WriteLine($"Elapsed Milliseconds: {stopwatch.ElapsedMilliseconds}");
        Console.WriteLine($"Elapsed Ticks: {stopwatch.ElapsedTicks}");
        
        // 检查计时器频率
        Console.WriteLine($"Frequency: {Stopwatch.Frequency} ticks per second");
        Console.WriteLine($"IsHighResolution: {Stopwatch.IsHighResolution}");
    }
}

2. 使用 DateTime.UtcNow(精度较低)

虽然不如 Stopwatch 精确,但在某些简单场景下可以使用:

csharp 复制代码
DateTime startTime = DateTime.UtcNow;

// 执行一些操作
for (int i = 0; i < 1000000; i++)
{
    var x = Math.Sqrt(i);
}

DateTime endTime = DateTime.UtcNow;
TimeSpan elapsed = endTime - startTime;

Console.WriteLine($"Elapsed Time: {elapsed}");

3. 使用 P/Invoke 调用 Windows 高精度计时器

如果需要更高精度或与原生代码交互,可以使用 Windows API:

csharp 复制代码
using System;
using System.Runtime.InteropServices;

class Program
{
    [DllImport("kernel32.dll")]
    private static extern bool QueryPerformanceCounter(out long lpPerformanceCount);

    [DllImport("kernel32.dll")]
    private static extern bool QueryPerformanceFrequency(out long lpFrequency);

    static void Main()
    {
        long frequency;
        QueryPerformanceFrequency(out frequency);
        
        long start;
        QueryPerformanceCounter(out start);
        
        // 执行一些操作
        for (int i = 0; i < 1000000; i++)
        {
            var x = Math.Sqrt(i);
        }
        
        long end;
        QueryPerformanceCounter(out end);
        
        double elapsed = (end - start) / (double)frequency;
        Console.WriteLine($"Elapsed Time: {elapsed} seconds");
    }
}

4. 使用 .NET Core 3.0+ 的 TimeProvider(.NET 6+)

在 .NET 6 及更高版本中,可以使用 TimeProvider 抽象:

csharp 复制代码
using System;

var timeProvider = TimeProvider.System;
long startTimestamp = timeProvider.GetTimestamp();

// 执行一些操作
for (int i = 0; i < 1000000; i++)
{
    var x = Math.Sqrt(i);
}

long endTimestamp = timeProvider.GetTimestamp();
double elapsed = timeProvider.GetElapsedTime(startTimestamp, endTimestamp).TotalSeconds;

Console.WriteLine($"Elapsed Time: {elapsed} seconds");

注意事项

  1. 精度差异

    • Stopwatch 通常提供最高精度(取决于硬件,可能是微秒级)
    • DateTime 的精度通常约为10-15毫秒
    • Windows 的 QueryPerformanceCounter 通常与 Stopwatch 精度相同
  2. 跨平台考虑

    • Stopwatch 在所有平台上都能提供最佳可用精度
    • 直接 P/Invoke 方法仅适用于 Windows
  3. 时间戳与日历时间

    • 高精度计时器通常返回的是相对于某个任意起点的时间戳,不是日历时间
    • 如果需要日历时间,应使用 DateTime.UtcNowDateTimeOffset.UtcNow

对于大多数性能测量场景,Stopwatch 是最佳选择。

注:内容由AI生成