你的位置:首页 > ASP.net教程

[ASP.net教程]如何计算代码的运行性能


  我们在开发的过程中,很多时候一个功能可能有多个实现方法,为了追求代码的性能,我们往往需要比较各实现方法的运行时间,从而选择性能最好的实现方法。那么怎样计算一段代码(或者说是函数)的运行时间呢,这个就是这篇文章我们要总结的内容。我们主要分以下几点来总结。

  1. 在C#代码中计算代码执行时间
  2. 在Sql Server中计算代码执行时间

在C#代码中计算代码执行时间

在C#程序中要计算代码段(或方法)的执行时间,我们一般都使用Stopwatch类,我比较了使用+=和使用StringBuilder分别拼接字符串的性能差异,示例代码如下。

 1 namespace ConsoleApplication5 2 { 3   class Program 4   { 5     static void Main(string[] args) 6     { 7       // 初始化性能计数器 8       CodeTimer.Initialize(); 9 10       // 定义执行次数11       int iteration = 100 * 1000; //10万次12 13       string s = string.Empty;14       CodeTimer.Time("String Concat", iteration, () => 15       {16         s += "a"; 17       });18 19       StringBuilder sb = new StringBuilder();20       CodeTimer.Time("StringBuilder", iteration, () => 21       {22         sb.Append("a"); 23       });24 25       Console.ReadKey();26     }27   }28 }

运行结果如下图。

我这里使用了封装的一个性能计时器,文章后面会附上源代码。

在Sql Server中计算代码执行时间

sql server中一般使用GetDate和DateDiff函数来计算sql语句运行的时间,示例代码如下。

 1 USE PackageFHDB; 2 GO 3  4 -- 开始时间 5 DECLARE @t1 AS DATETIME; 6 SELECT @t1= GETDATE(); 7  8 -- 运行的sql语句 9 SELECT TOP 1000 * FROM dbo.Pkg_PkgOrderMaster;10 11 -- 打印结果12 PRINT DATEDIFF(millisecond,@t1,GETDATE());

执行结果为293毫秒,如下图。

附:性能计时器的源代码

 1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 using System.Diagnostics; 6 using System.Threading; 7 using LNFramework.Common.Extends; 8 using System.Runtime.InteropServices; 9 10 namespace LNFramework.Common.Tools11 {12   /// <summary>13   /// 性能计时器14   /// </summary>15   public static class CodeTimer16   {17     /// <summary>18     /// 初始化19     /// </summary>20     public static void Initialize()21     {22       // 将当前进程及线程的优先级设为最高,减少操作系统在调度上造成的干扰23       // 然后调用一次Time方法进行预热,以便让Time方法尽快进入状态24       Process.GetCurrentProcess().PriorityClass = ProcessPriorityClass.High;25       Thread.CurrentThread.Priority = ThreadPriority.Highest;26       Time("", 1, () => { });27     }28 29     /// <summary>30     /// 计时31     /// </summary>32     /// <param name="name">名称</param>33     /// <param name="iteration">循环次数</param>34     /// <param name="action">方法体</param>35     public static void Time(string name, int iteration, Action action)36     {37       if (name.IsNullOrEmpty()) return;38 39       // 1.保留当前控制台前景色,并使用黄色输出名称参数40       ConsoleColor currentForeColor = Console.ForegroundColor;41       Console.ForegroundColor = ConsoleColor.Yellow;42       Console.WriteLine(name);43 44       // 2.强制GC进行收集,并记录目前各代已经收集的次数45       GC.Collect(GC.MaxGeneration, GCCollectionMode.Forced);46       int[] gcCounts = new int[GC.MaxGeneration + 1];47       for (int i = 0; i <= GC.MaxGeneration; i++)48       {49         gcCounts[i] = GC.CollectionCount(i);50       }51 52       // 3.执行代码,记录下消耗的时间及CPU时钟周期53       Stopwatch watch = new Stopwatch();54       watch.Start();55       ulong cycleCount = GetCycleCount();56       for (int i = 0; i < iteration; i++)57       {58         action();59       }60       ulong cpuCycles = GetCycleCount() - cycleCount;61       watch.Stop();62 63       // 4.恢复控制台默认前景色,并打印出消耗时间及CPU时钟周期64       Console.ForegroundColor = currentForeColor;65       Console.WriteLine("\tTime Elapsed:\t" + watch.ElapsedMilliseconds.ToString("N0") + "ms");66       Console.WriteLine("\tCPU Cycles:\t" + cpuCycles.ToString("N0"));67 68       // 5.打印执行过程中各代垃圾收集回收次数69       for (int i = 0; i <= GC.MaxGeneration; i++)70       {71         int count = GC.CollectionCount(i) - gcCounts[i];72         Console.WriteLine("\tGen " + i + ": \t\t" + count);73       }74 75       Console.WriteLine();76     }77 78     private static ulong GetCycleCount()79     {80       ulong cycleCount = 0;81       QueryThreadCycleTime(GetCurrentThread(), ref cycleCount);82       return cycleCount;83     }84 85     [DllImport("kernel32.dll")]86     [return: MarshalAs(UnmanagedType.Bool)]87     static extern bool QueryThreadCycleTime(IntPtr threadHandle, ref ulong cycleTime);88 89     [DllImport("kernel32.dll")]90     static extern IntPtr GetCurrentThread();91   }92 }

View Code

参考文章:

一个简单的性能计数器:CodeTimer