博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
将不确定变为确定~老赵写的CodeTimer是代码性能测试的利器
阅读量:6902 次
发布时间:2019-06-27

本文共 6343 字,大约阅读时间需要 21 分钟。

首先,非常感谢赵老大的CodeTimer,它让我们更好的了解到代码执行的性能,从而可以让我们从性能的角度来考虑问题,有些东西可能我们认为是这样的,但经理测试并非如何,这正应了我之前的那名话:“机器最能证明一切”!

费话就不说了,看代码吧:

1     ///   2     /// 执行代码规范  3     ///   4     public interface IAction  5     {  6         void Action();  7     }  8   9     ///  10     /// 老赵的性能测试工具 11     ///  12     public static class CodeTimer 13     { 14         [DllImport("kernel32.dll", SetLastError = true)] 15         static extern bool GetThreadTimes(IntPtr hThread, out long lpCreationTime, out long lpExitTime, out long lpKernelTime, out long lpUserTime); 16  17         [DllImport("kernel32.dll")] 18         static extern IntPtr GetCurrentThread(); 19         public delegate void ActionDelegate(); 20         private static long GetCurrentThreadTimes() 21         { 22             long l; 23             long kernelTime, userTimer; 24             GetThreadTimes(GetCurrentThread(), out l, out l, out kernelTime, out userTimer); 25             return kernelTime + userTimer; 26         } 27         static CodeTimer() 28         { 29             Process.GetCurrentProcess().PriorityClass = ProcessPriorityClass.High; 30             Thread.CurrentThread.Priority = ThreadPriority.Highest; 31         } 32         public static void Time(string name, int iteration, ActionDelegate action) 33         { 34             if (String.IsNullOrEmpty(name)) 35             { 36                 return; 37             } 38             if (action == null) 39             { 40                 return; 41             } 42  43             //1. Print name 44             ConsoleColor currentForeColor = Console.ForegroundColor; 45             Console.ForegroundColor = ConsoleColor.Yellow; 46             Console.WriteLine(name); 47  48             // 2. Record the latest GC counts 49             //GC.Collect(GC.MaxGeneration, GCCollectionMode.Forced); 50             GC.Collect(GC.MaxGeneration); 51             int[] gcCounts = new int[GC.MaxGeneration + 1]; 52             for (int i = 0; i <= GC.MaxGeneration; i++) 53             { 54                 gcCounts[i] = GC.CollectionCount(i); 55             } 56  57             // 3. Run action 58             Stopwatch watch = new Stopwatch(); 59             watch.Start(); 60             long ticksFst = GetCurrentThreadTimes(); //100 nanosecond one tick 61             for (int i = 0; i < iteration; i++) action(); 62             long ticks = GetCurrentThreadTimes() - ticksFst; 63             watch.Stop(); 64  65             // 4. Print CPU 66             Console.ForegroundColor = currentForeColor; 67             Console.WriteLine("\tTime Elapsed:\t\t" + 68                watch.ElapsedMilliseconds.ToString("N0") + "ms"); 69             Console.WriteLine("\tTime Elapsed (one time):" + 70                (watch.ElapsedMilliseconds / iteration).ToString("N0") + "ms"); 71             Console.WriteLine("\tCPU time:\t\t" + (ticks * 100).ToString("N0") 72                + "ns"); 73             Console.WriteLine("\tCPU time (one time):\t" + (ticks * 100 / 74                iteration).ToString("N0") + "ns"); 75  76             // 5. Print GC 77             for (int i = 0; i <= GC.MaxGeneration; i++) 78             { 79                 int count = GC.CollectionCount(i) - gcCounts[i]; 80                 Console.WriteLine("\tGen " + i + ": \t\t\t" + count); 81             } 82             Console.WriteLine(); 83         } 84  85  86  87         public static void Time(string name, int iteration, IAction action) 88         { 89             if (String.IsNullOrEmpty(name)) 90             { 91                 return; 92             } 93  94             if (action == null) 95             { 96                 return; 97             } 98  99             //1. Print name100             ConsoleColor currentForeColor = Console.ForegroundColor;101             Console.ForegroundColor = ConsoleColor.Yellow;102             Console.WriteLine(name);103 104             // 2. Record the latest GC counts105             //GC.Collect(GC.MaxGeneration, GCCollectionMode.Forced);106             GC.Collect(GC.MaxGeneration);107             int[] gcCounts = new int[GC.MaxGeneration + 1];108             for (int i = 0; i <= GC.MaxGeneration; i++)109             {110                 gcCounts[i] = GC.CollectionCount(i);111             }112 113             // 3. Run action114             Stopwatch watch = new Stopwatch();115             watch.Start();116             long ticksFst = GetCurrentThreadTimes(); //100 nanosecond one tick117             for (int i = 0; i < iteration; i++) action.Action();118             long ticks = GetCurrentThreadTimes() - ticksFst;119             watch.Stop();120 121             // 4. Print CPU122             Console.ForegroundColor = currentForeColor;123             Console.WriteLine("\tTime Elapsed:\t\t" +124                watch.ElapsedMilliseconds.ToString("N0") + "ms");125             Console.WriteLine("\tTime Elapsed (one time):" +126                (watch.ElapsedMilliseconds / iteration).ToString("N0") + "ms");127             Console.WriteLine("\tCPU time:\t\t" + (ticks * 100).ToString("N0")128                 + "ns");129             Console.WriteLine("\tCPU time (one time):\t" + (ticks * 100 /130                 iteration).ToString("N0") + "ns");131 132             // 5. Print GC133             for (int i = 0; i <= GC.MaxGeneration; i++)134             {135                 int count = GC.CollectionCount(i) - gcCounts[i];136                 Console.WriteLine("\tGen " + i + ": \t\t\t" + count);137             }138             Console.WriteLine();139         }140     }

有了上面的codeTimer我们就来测试一个吧,如字条串和并的问题,用+=还是用StringBuilder呢,有点经验的程序员肯定说是StringBuilder,是的,确实是后者,那我们就来看看这

两种方法测试的结果吧

1      CodeTimer.Time("String  Concat", 100000, 2                  () => 3                  { 4                      var s = "1"; 5                      for (int i = 1; i < 10; i++) 6                          s = s + "1"; 7                  }); 8  9       CodeTimer.Time("StringBuilder Concat", 100000,10                () =>11                {12                    var s = new StringBuilder();13                    for (int i = 1; i < 10; i++)14                        s.Append("1");15                });

测试的结果如下:

从图中我们可以看到StringBuilder快的很明显,无论是执行时间,还是对CPU的消耗及GC回收都远低于String的拼结,所以,才有以下结论:

在字符串拼结时,请使用StringBuilder吧!

转载于:https://www.cnblogs.com/lori/archive/2012/07/19/2599604.html

你可能感兴趣的文章
常用软件包下载网址
查看>>
Vagrant中Apache或Nginx,修改css/js等静态文件不生效的解决方案
查看>>
Arduino学习笔记01——单个LED灯闪烁
查看>>
学习linux计划书
查看>>
我的友情链接
查看>>
我的友情链接
查看>>
Hapoxy--基础篇
查看>>
centons 6.4 vsftpd部署
查看>>
ftp在强制模式下允许匿名用户上传文件
查看>>
处理Elasticsearch集群yellow和red状态
查看>>
我的友情链接
查看>>
android编译系统makefile(Android.mk)写法
查看>>
我的友情链接
查看>>
我的友情链接
查看>>
Android UI开发第二十八篇——Fragment中使用左右滑动菜单
查看>>
[awk] 用-F指定多分隔符实例_备忘
查看>>
我的友情链接
查看>>
C++字符串高效查找替换
查看>>
62.菜鸟福音 60条笔记本电脑使用经典技巧
查看>>
mysql全备脚本,此脚本可以备份多个数据库,单独文件夹
查看>>