C#中Stopwatch类实现精确代码执行时间测量的两种方案

 更新时间:2026年04月13日 08:50:12   作者:码农刚子  
本文将介绍如何使用System.Diagnostics.Stopwatch类实现高精度的执行时间测量,并提供基础用法和进阶实现两种方案,感兴趣的朋友跟随小编一起看看吧

C#中Stopwatch类实现精确代码执行时间测量

在C#开发中,精确测量代码执行时间对于性能优化和算法对比至关重要。本文将介绍如何使用System.Diagnostics.Stopwatch类实现高精度的执行时间测量,并提供基础用法和进阶实现两种方案。

基础Stopwatch用法

Stopwatch类提供了简单直接的时间测量方式,适用于单次操作耗时分析。

using System;
using System.Diagnostics;
class Program
{
    static void Main()
    {
        var stopwatch = Stopwatch.StartNew();
        // 模拟耗时操作
        for (int i = 0; i < 1000000; i++) { }
        stopwatch.Stop();
        Console.WriteLine($"基础用法 - 执行时间: {stopwatch.ElapsedMilliseconds}ms");
        Console.WriteLine($"精确时间: {stopwatch.Elapsed.TotalSeconds:F6}秒");
    }
}

关键API说明

  • StartNew():创建并立即启动计时器
  • Stop():停止计时
  • ElapsedMilliseconds:获取毫秒级耗时
  • Elapsed.TotalSeconds:获取精确到秒的小数

进阶计时器实现

对于需要多次测量和统计平均值的场景,可以封装CodeTimer类实现更复杂的功能。

using System;
using System.Collections.Generic;
using System.Diagnostics;
class CodeTimer
{
    private Stopwatch _stopwatch = new Stopwatch();
    private Queue<long> _timeRecords = new Queue<long>();
    private long _totalTime;
    private const int MaxRecords = 10;
    public double AverageTimeMs => _timeRecords.Count > 0 ? _totalTime / (double)_timeRecords.Count : 0;
    public void Start()
    {
        _stopwatch.Restart();
    }
    public void StopAndPrint(string operationName)
    {
        _stopwatch.Stop();
        long elapsedMs = _stopwatch.ElapsedMilliseconds;
        _timeRecords.Enqueue(elapsedMs);
        _totalTime += elapsedMs;
        if (_timeRecords.Count > MaxRecords)
        {
            _totalTime -= _timeRecords.Dequeue();
        }
        Console.WriteLine($"{operationName}: {elapsedMs}ms");
    }
}

进阶功能

  • 自动计算多次执行的平均时间
  • 滑动窗口统计(默认保留最近10次记录)
  • 方便的打印输出功能

两种方案对比

特性基础方案进阶方案
适用场景单次操作耗时分析多次执行统计/性能趋势分析
功能复杂度
内存占用极低中等(存储历史记录)
输出信息原始时间数据格式化输出+统计值

最佳实践建议

  • 测量环境准备
    • 关闭其他占用CPU的程序
    • 在Release模式下运行
    • 预热代码(首次运行可能较慢)
  • 测量精度控制
    • 避免在测量代码中包含I/O操作
    • 测量足够长的操作(>1ms)
    • 多次测量取平均值
  • 结果分析
    • 关注时间变化趋势而非绝对值
    • 对比不同实现时使用相同测试环境
    • 记录测试时的系统负载情况

以下内容为补充知识,需要的朋友拿去用。

C# 减少代码运行时间的7 个实战技巧

前言

想象一下,你正在一家忙碌的咖啡馆里工作,顾客络绎不绝,你不停地跑前跑后,累得直喘气。

如果你能同时准备几杯咖啡,效率是不是会大大提高?

这就是并发编程的魅力所在。

今天,我们就来聊聊 C# 中的 Task,看看它是如何帮助我们在代码中实现“多任务并行”的奇迹。

1. Task.Run:简单高效的启动方式

// 使用 Task.Run 来快速启动一个后台任务
Task.Run(() => 
{
    Console.WriteLine($"任务运行在线程 {Thread.CurrentThread.ManagedThreadId}");
    Thread.Sleep(1000); // 模拟耗时操作
    Console.WriteLine("任务完成!");
});

解释:这是最常用的启动异步任务的方法,适合执行一些不需要立即返回结果的操作。

2. Task.Factory.StartNew:灵活应对各种需求

// 使用 Task.Factory.StartNew 来处理长时间运行的任务
Task.Factory.StartNew(() => 
{
    Console.WriteLine($"任务运行在线程 {Thread.CurrentThread.ManagedThreadId}");
    // 模拟CPU密集型计算
    for (int i = 0; i < 1000000; i++) {}
}, TaskCreationOptions.LongRunning); // 提示这是一个长任务

提示:对于需要较长时间才能完成的任务,这种方式可以提供更多的控制选项。

3. new Task:手动管理任务

var task = new Task(() => 
{
    Console.WriteLine($"任务运行在线程 {Thread.CurrentThread.ManagedThreadId}");
    File.WriteAllText("test.txt", "Hello Task!");
});
task.Start(); // 需要手动启动任务

注意:虽然这种方法提供了对任务生命周期的完全控制,但在大多数情况下,推荐使用更简便的方式。

4. 多任务并行处理

var tasks = new List<Task>();
for (int i = 0; i < 5; i++)
{
    int taskId = i; // 避免闭包陷阱
    tasks.Add(Task.Run(() => 
    {
        Console.WriteLine($"任务{taskId}开始执行");
        Thread.Sleep(1000 * (taskId + 1));
        Console.WriteLine($"任务{taskId}完成");
    }));
}
await Task.WhenAll(tasks); // 等待所有任务完成
Console.WriteLine("所有任务都完成了!");

小贴士:合理利用多任务并行处理,可以大幅缩短程序的执行时间。

5. 带返回值的任务

Task<int> fibonacciTask = Task.Run(() => 
{
    int Fib(int n) => n <= 1 ? n : Fib(n - 1) + Fib(n - 2);
    return Fib(35); // 计算斐波那契数列第35项
});
Console.WriteLine("正在拼命计算中...");
int result = await fibonacciTask;
Console.WriteLine($"计算结果: {result}");

亮点:通过返回值,你可以轻松地在异步任务完成后获取其结果。

6. 任务链式调用

Task.Run(() => 
{
    Console.WriteLine("第一阶段:数据准备");
    return"原始数据";
})
.ContinueWith(previousTask => 
{
    Console.WriteLine($"第二阶段:处理 {previousTask.Result}");
    return$"处理后的-{previousTask.Result}";
})
.ContinueWith(previousTask => 
{
    Console.WriteLine($"第三阶段:存储 {previousTask.Result}");
    File.WriteAllText("data.txt", previousTask.Result);
});

好处:链式调用不仅能让代码看起来更整洁,还能确保各阶段按顺序执行。

总结

恭喜你,现在你应该已经掌握了使用 Task 进行多线程编程的基础知识和一些高级技巧。

记住,实践是检验真理的唯一标准。

到此这篇关于C#中Stopwatch类实现精确代码执行时间测量的两种方案的文章就介绍到这了,更多相关C# Stopwatch类代码执行时间测量内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • C#实现类型的比较示例详解

    C#实现类型的比较示例详解

    这篇文章主要给大家介绍了关于C#实现类型的比较的相关资料,文中通过示例代码介绍的非常详细,对大家学习或者使用C#具有一定的参考学习价值,需要的朋友们下面来一起学习学习吧
    2019-04-04
  • c#给图片添加文字的代码小结

    c#给图片添加文字的代码小结

    c#编程中,我们需要为图片添加文字水印,那么就可以参考下面的几个代码
    2012-11-11
  • HighCharts图表控件在ASP.NET WebForm中的使用总结(全)

    HighCharts图表控件在ASP.NET WebForm中的使用总结(全)

    这篇文章主要介绍了HighCharts图表控件在ASP.NET WebForm中的使用总结(全),需要的朋友可以参考下
    2015-08-08
  • C#如何给word文档添加水印

    C#如何给word文档添加水印

    这篇文章主要为大家详细介绍了C#如何给word文档添加水印的相关资料,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2016-09-09
  • C# 中用 Sqlparameter 的两种用法

    C# 中用 Sqlparameter 的两种用法

    这篇文章主要介绍了C# 中用 Sqlparameter 的几种用法,文中给大家列举了两种用法,非常不错,具有一定的参考借鉴价值,需要的朋友可以参考下
    2018-09-09
  • C# List实现行转列的通用方案

    C# List实现行转列的通用方案

    本篇通过行转列引出了System.Linq.Dynamic,并且介绍了过滤功能,具有很好的参考价值。下面跟着小编一起来看下吧
    2017-03-03
  • 轻松学习C#的结构和类

    轻松学习C#的结构和类

    轻松学习C#的结构和类,对C#的结构和类感兴趣的朋友可以参考本篇文章,帮助大家更灵活的运用C#的结构和类
    2015-11-11
  • DevExpress获取节点下可视区域子节点集合的实现方法

    DevExpress获取节点下可视区域子节点集合的实现方法

    这篇文章主要介绍了DevExpress获取节点下可视区域子节点集合的实现方法,是C#程序设计中较为常见的技巧,需要的朋友可以参考下
    2014-08-08
  • winform壁纸工具为图片添加当前月的日历信息

    winform壁纸工具为图片添加当前月的日历信息

    使用用winform做了一个设置壁纸小工具,为图片添加当月的日历并设为壁纸,可以手动/定时设置壁纸,最主要的特点是在图片上生成当前月的日历信息,感兴趣的你可以参考下
    2013-03-03
  • C#中Lambda表达式的三种写法

    C#中Lambda表达式的三种写法

    这篇文章介绍了C#中Lambda表达式的三种写法,文中通过示例代码介绍的非常详细。对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2022-05-05

最新评论