统计代码执行时间,使用Stopwatch和UserProcessorTime的区别
当我们需要统计一段代码的执行时间,首先想到的可能是Stopwatch类。在这里,先暂不使用Stopwatch,自定义一个统计代码执行时间的类,大致需要考虑到:
1、确保统计的是当前进程、当前线程中代码的执行时间。
2、在统计执行过程中,不允许有垃圾回收。即在统计代码执行时间之前,就让GC完成垃圾回收。
举例:统计显示一个数组元素所消耗的时间
class Program
{static void Main(string[] args){int[] arrs = new int[10000];BuildArray(arrs);CalculateTiming calculateTiming = new CalculateTiming();
calculateTiming.Start();DisplaySomeDigits(arrs);calculateTiming.Stop();Console.WriteLine("所耗费时间为:" + calculateTiming.Result().TotalMilliseconds + "毫秒");}//显示数组元素
static void DisplaySomeDigits(int[] arr){for (int i = 0; i < arr.Length; i++){Console.Write(arr[i] + " ");
}}//创建数组
static void BuildArray(int[] arr){for (int i = 0; i < arr.Length; i++){arr[i] = i;}}}/// <summary>
/// 计算CPU消耗时间
/// </summary>
public class CalculateTiming{private TimeSpan startTime;
private TimeSpan duration;
public CalculateTiming()
{startTime = new TimeSpan(0);
duration = new TimeSpan(0);
}public void Start(){//手动执行垃圾回收
GC.Collect();//挂起当前线程,直到使用GC对所有托管堆上的对象实施Finalize方法
GC.WaitForPendingFinalizers();//获取当前进程、当前线程执行的起始时间
startTime = Process.GetCurrentProcess().Threads[0].UserProcessorTime;}public void Stop(){//获取当前进程、当前线程执行所消耗的时间
duration = Process.GetCurrentProcess().Threads[0].UserProcessorTime.Subtract(startTime);}public TimeSpan Result()
{return duration;
}}
以上,通过当前进程、当前线程的UserProcessorTime属性来统计代码执行时间。
如果使用Stopwatch来统计代码执行时间。
static void Main(string[] args){int[] arrs = new int[10000];BuildArray(arrs);Stopwatch sw = new Stopwatch();
sw.Start();DisplaySomeDigits(arrs);sw.Stop();Console.WriteLine("所耗费时间为:" + sw.ElapsedMilliseconds + "毫秒");}
为什么使用Stopwatch统计代码执行时间,耗费时间更长呢?
--使用UserProcessorTime属性来统计,统计的是当前进程、当前线程所消耗的CPU执行时间。而Stopwatch统计的代码执行时间,不仅包括了CPU的执行时间,还包括了在电脑屏幕上显示字符串所占用的I/0时间。