C# Stopwatch 程序性能测量

1.定义

Stopwatch 可以测量一个时间间隔的运行时间,也可以测量多个时间间隔的总运行时间。一般用来测量代码执行所用的时间或者计算性能数据,在优化代码性能上可以使用Stopwatch来测量时间。

2.API

namespace System.Diagnostics  
{  
    //  
    // 摘要:  
    //     提供一组方法和属性,可用于准确地测量运行时间。  
    public class Stopwatch  
    {  
        //  
        // 摘要:  
        //     获取以每秒计时周期数表示的计时器频率。此字段为只读。  
        public static readonly long Frequency;  
        //  
        // 摘要:  
        //     指示计时器是否基于高分辨率性能计数器。此字段为只读。  
        public static readonly bool IsHighResolution;  
  
        //  
        // 摘要:  
        //     初始化 System.Diagnostics.Stopwatch 类的新实例。  
        public Stopwatch();  
  
        //  
        // 摘要:  
        //     获取当前实例测量得出的总运行时间。  
        //  
        // 返回结果:  
        //     一个只读的 System.TimeSpan,用于表示当前实例测量得出的总运行时间。  
        public TimeSpan Elapsed { get; }  
        //  
        // 摘要:  
        //     获取当前实例测量得出的总运行时间(以毫秒为单位)。  
        //  
        // 返回结果:  
        //     一个只读长整型,表示当前实例测量得出的总毫秒数。  
        public long ElapsedMilliseconds { get; }  
        //  
        // 摘要:  
        //     获取当前实例测量得出的总运行时间(用计时器计时周期表示)。  
        //  
        // 返回结果:  
        //     一个只读长整型,表示当前实例测量得出的计时器计时周期的总数。  
        public long ElapsedTicks { get; }  
        //  
        // 摘要:  
        //     获取一个指示 System.Diagnostics.Stopwatch 计时器是否在运行的值。  
        //  
        // 返回结果:  
        //     如果 System.Diagnostics.Stopwatch 实例当前正在运行,并且在对某个时间间隔的运行时间进行测量,则该值为 true;否则为 false。  
        public bool IsRunning { get; }  
  
        //  
        // 摘要:  
        //     获取计时器机制中的当前最小时间单位数。  
        //  
        // 返回结果:  
        //     一个长整型,表示基础计时器机制中的计时周期计数器值。  
        public static long GetTimestamp();  
        //  
        // 摘要:  
        //     对新的 System.Diagnostics.Stopwatch 实例进行初始化,将运行时间属性设置为零,然后开始测量运行时间。  
        //  
        // 返回结果:  
        //     刚刚开始测量运行时间的 System.Diagnostics.Stopwatch。  
        public static Stopwatch StartNew();  
        //  
        // 摘要:  
        //     停止时间间隔测量,并将运行时间重置为零。  
        public void Reset();  
        //  
        // 摘要:  
        //     停止时间间隔测量,将运行时间重置为零,然后开始测量运行时间。  
        public void Restart();  
        //  
        // 摘要:  
        //     开始或继续测量某个时间间隔的运行时间。  
        public void Start();  
        //  
        // 摘要:  
        //     停止测量某个时间间隔的运行时间。  
        public void Stop();  
    }  
}

3.使用示例

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Diagnostics;

namespace BoxAndUnBox
{
    class Program
    {
        static void Main(string[] args)
        {
            Stopwatch watch = new Stopwatch();
            watch.Start();
            long result = SumWithoutBox();
            watch.Stop();
            Console.WriteLine("SumWithoutBox()方法返回计算结果:{0},用时{1}毫秒",
               result, watch.ElapsedMilliseconds);//获取当前实例测量得出的总运行时间(以毫秒为单位)
            watch.Restart();
            result = SumWithBox();
            watch.Stop();
            Console.WriteLine("SumWithBox()方法返回计算结果:{0},用时{1}毫秒",
         result, watch.ElapsedMilliseconds);
            Console.ReadKey();
        }

        static long SumWithoutBox()
        {
            long sum = 0;
            for (long i = 0; i < 10000000; i++)
                sum += i;
            return sum;
        }

        static long SumWithBox()
        {
            object sum = 0L; //装箱
            for (long i = 0; i < 10000000; i++)
                sum = (long)sum + i;//先拆箱,求和,再装箱
            return (long)sum;//拆箱
        }
    }
}

在这里插入图片描述

<think>好的,我现在需要帮助用户了解如何在C#测量程序的执行时间。根据用户的问题,他可能是一个刚开始学习C#的开发者,想要优化代码性能或者进行基准测试。首先,我需要回顾C#中常用的时间测量方法,确保信息的准确性。 首先想到的是Stopwatch类,它属于System.Diagnostics命名空间,提供了高精度的时间测量。这应该是首选方法,因为它使用高分辨率计时器,适合性能测试。需要提醒用户正确使用StartNew()和Stop()方法,并注意Elapsed属性。 然后,DateTime类也是一个选项,但精度可能较低,适用于粗略测量。比如用DateTime.Now记录开始和结束时间,再相减得到总时间。不过要指出这种方法可能受系统时间调整影响,不适合高精度需求。 接下来,用户可能需要进行多次运行以获得平均结果,特别是考虑到JIT编译预热的影响。引用[1]提到C#有预热功能,首次执行可能较慢,所以应该建议用户执行多次测试,排除首次运行的影响。 另外,引用[1]中还提到了异步任务和通道的测试,这可能涉及到多线程或异步编程中的时间测量。需要提醒用户在异步代码中正确使用Stopwatch,确保测量点正确,比如在异步方法前后启动和停止计时器。 还要考虑代码示例的清晰性,给出简单的示例帮助用户理解。例如,用Stopwatch的典型用法,包括using System.Diagnostics;的引入,以及正确调用StartNew和Stop。 同时,需要指出可能的误区,比如多次测量取平均值的重要性,避免单次测量的偶然性。此外,用户可能需要知道如何处理环境因素,如其他进程的影响,建议在安静的环境下测试。 最后,根据用户提供的引用内容,特别是引用[1]中提到的预热功能,要强调在测量前执行一次测试代码,确保JIT编译已经完成,避免首次执行的额外时间影响结果。这可能涉及到在正式测试前先运行一次被测代码,而不计入时间统计。 总结步骤:介绍Stopwatch和DateTime两种方法,给出代码示例,强调预热和多次测量,注意事项如环境因素和异步处理。这样用户就能全面了解如何在C#中准确测量执行时间了。</think>### 如何在C#测量程序执行时间? 在C#测量程序执行时间主要有两种常用方法:使用`Stopwatch`类或`DateTime`类。以下为具体实现步骤和注意事项: --- #### 方法1:使用`Stopwatch`类(高精度推荐) `System.Diagnostics.Stopwatch`类提供高精度计时功能(基于硬件计时器),适用于性能测试和基准分析。 ```csharp using System; using System.Diagnostics; public class Program { public static void Main() { Stopwatch stopwatch = Stopwatch.StartNew(); // 待测试的代码 for (int i = 0; i < 1000000; i++) { // 模拟耗时操作 } stopwatch.Stop(); Console.WriteLine($"执行时间:{stopwatch.ElapsedMilliseconds} 毫秒"); } } ``` **关键点**: - 通过`StartNew()`启动计时器 - 使用`Elapsed`属性获取时间差(支持毫秒`ElapsedMilliseconds`或更精确的`ElapsedTicks`) - 精度可达微秒级别[^1] --- #### 方法2:使用`DateTime`类(简单场景) 适用于粗略时间测量,精度受系统时钟限制(通常约15毫秒)。 ```csharp DateTime startTime = DateTime.Now; // 待测试的代码 System.Threading.Thread.Sleep(1000); DateTime endTime = DateTime.Now; TimeSpan duration = endTime - startTime; Console.WriteLine($"执行时间:{duration.TotalMilliseconds} 毫秒"); ``` --- #### 优化测量准确性 1. **预热执行** 首次运行可能因JIT编译导致耗时增加,需先执行一次测试代码: ```csharp // 预热(不纳入计时) MyMethodToMeasure(); Stopwatch stopwatch = Stopwatch.StartNew(); MyMethodToMeasure(); ``` 2. **多次测量取平均值** 通过循环执行多次计算平均耗时,减少环境干扰: ```csharp int runs = 10; long totalTime = 0; for (int i = 0; i < runs; i++) { Stopwatch sw = Stopwatch.StartNew(); MyMethod(); sw.Stop(); totalTime += sw.ElapsedMilliseconds; } Console.WriteLine($"平均耗时:{totalTime / runs} 毫秒"); ``` 3. **避免后台进程干扰** 关闭不必要的应用程序,确保测试环境稳定[^1]。 --- #### 异步代码测量 若涉及异步任务,需确保计时器覆盖完整的异步操作生命周期: ```csharp Stopwatch stopwatch = Stopwatch.StartNew(); await MyAsyncMethod(); stopwatch.Stop(); ``` --- ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值