用于.NET环境的时间测试

本文介绍了在.NET环境下如何准确地测试代码执行时间。包括如何控制垃圾回收时机、等待终结器方法执行完毕以及如何利用Process类获取当前进程的执行时间。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

     在.Net环境中,我们需要考虑我们的程序所运行的线程及任何时候垃圾回收都可能发生的事实。我们需要在设计我们的计时代码时将这些因素考虑在内。

     让我们先来看一下怎样控制垃圾回收。首先,我们讨论一下垃圾回收的作用。在C#中,引用类型(如字符串,数组及类的实例对象)的内存空间是在被称作堆的空间中分配的。堆是一片用来保存数据项(之前提到的类型)的内存空间。值类型,如普通的变量,被存储在栈上。到引用类型数据的引用也是存储在栈上,但是引用类型中实际存储的数据被保存在栈中。存储在栈上的变量当声明它的子程序执行完成时被释放。另一方面,存储在托管堆上的变量一直存在堆中直到垃圾回收过程被调用。堆数据只有在没有对它的动态引用时通过垃圾回收被移除。垃圾回收可以并且将会发生在程序执行的任意时刻。然而,我们要尽我们可能的确保垃圾回收器在我们计时代码执行的过程中不运行。我们可以通过强制调用垃圾回收器来阻止任意执行的垃圾回收。.Net环境中提供了与个特殊的对象 – GC供调用垃圾回收使用。要通知系统执行垃圾回收。我们简单的写:

GC.Collect();

    然而,这不是全部我们必须做的。存储在堆中的每一个对象有一个成为终结器的特殊方法。终结器方法在对象被删除前的最后一步执行。终结器方法存在的问题是它们不以一种规律的方式执行。事实上,你甚至根本不能确定一个对象的终结器是否已经运行了。但是我们知道,在我们确定一个对象被删除之前,它的终结器方法一定会运行。要确保这一点,我们添加一行代码来告诉程序等待所有堆上的对象的终结器方法运行后再继续执行。这行代码如下:

GC.WaitForPendingFinalizers();

我们已经清除了一个障碍并且只剩一个待解决 – 使用适当的线程。在.Net环境中,一个程序运行在一个线程中,也被称作应用程序域。这允许操作系统将每一个不同的程序分开在其上同时运行。在一个进程中,程序或者程序的一部分在一个线程内运行。一个程序的执行时间被操作系统通过线程进行分配。当我们为一个程序的代码计时时,我们想要确保我们计的时间只是进程分配给我的程序的代码所占用的时间,而不是操作系统执行的其他任务的时间。

我们可以使用.NET类库中的Process类来实现这个功能。Process类的方法允许我们选择当前进程(我们的程序正运行的进程),程序正运行的线程,及一个计时器来存储线程开始执行的时间。所有这些方法可合并入一次调用,并指定这个调用函数的返回值为存储线程开始执行的时间(一个TimeSpan对象)的变量。如下是代码(共有两行)。

TimeSpan startingTime;

startingTime = Process.GetCurrentProcess().Threads[0] .UserProcessorTime;

剩下的我们只需捕获我们计时的代码段停止的时间。代码示例如下:

duration = Process.GetCurrentProcess().Threads[0].UserProcessorTime .Subtract(startingTime);

        static void BuildArray(int[] arr)
        {
            for (int i = 0; i <= 99999; i++)
                arr[i] = i;
        }

        static void DisplayNums(int[] arr)
        {
            for (int i = 0; i <= arr.GetUpperBound(0); i++)
                Console.Write(arr[i] +" ");
        }

        static void Main(string[] args)
        {
            TimeSpan t = new TimeSpan();
            int[] nums = new int[100000];
            BuildArray(nums);
            TimeSpan duration;
            DisplayNums(nums);
            DisplayNums(nums);
            DisplayNums(nums);
            duration = Process.GetCurrentProcess().TotalProcessorTime;
            Console.WriteLine("Time:" + duration.TotalSeconds); 
            Console.ReadKey();
        }


 

 public class Timing
    {
        TimeSpan duration;

        public Timing()
        {
            duration = new TimeSpan(0);
        }

        public void stopTime()
        {
            duration = Process.GetCurrentProcess().TotalProcessorTime;//执行当前线程使用的时间
        }

        public void startTime()
        {
            GC.Collect(); //强制对所有代进行即时垃圾回收
            GC.WaitForPendingFinalizers(); //挂起当前线程,直到处理终结器队列的线程清空该队列为止
        }

        public TimeSpan Result()
        {
            return duration;
        }
    }

 

posted on 2010-01-25 22:40 OTO 阅读( ...) 评论( ...) 编辑 收藏

转载于:https://www.cnblogs.com/souso/archive/2010/01/25/1656274.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值