
·您现在的位置: 云翼网络 >> 文章中心 >> 网站建设 >> 网站建设开发 >> ASP.NET网站开发 >> 如何计算代码的运行性能
我们在开发的过程中,很多时候一个功能可能有多个实现方法,为了追求代码的性能,我们往往需要比较各实现方法的运行时间,从而选择性能最好的实现方法。那么怎样计算一段代码(或者说是函数)的运行时间呢,这个就是这篇文章我们要总结的内容。我们主要分以下几点来总结。
在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中一般使用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.Tools
11 {
12 /// <summary>
13 /// 性能计时器
14 /// </summary>
15 public static class CodeTimer
16 {
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