将不确定变为确定~老赵写的CodeTimer是代码性能测试的利器

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

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

复制代码
  1     /// <summary>2     /// 执行代码规范3     /// </summary>4     public interface IAction5     {6         void Action();7     }8 9     /// <summary>10     /// 老赵的性能测试工具11     /// </summary>12     public static class CodeTimer13     {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 name44             ConsoleColor currentForeColor = Console.ForegroundColor;45             Console.ForegroundColor = ConsoleColor.Yellow;46             Console.WriteLine(name);47 48             // 2. Record the latest GC counts49             //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 action58             Stopwatch watch = new Stopwatch();59             watch.Start();60             long ticksFst = GetCurrentThreadTimes(); //100 nanosecond one tick61             for (int i = 0; i < iteration; i++) action();62             long ticks = GetCurrentThreadTimes() - ticksFst;63             watch.Stop();64 65             // 4. Print CPU66             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 GC77             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 name
100             ConsoleColor currentForeColor = Console.ForegroundColor;
101             Console.ForegroundColor = ConsoleColor.Yellow;
102             Console.WriteLine(name);
103 
104             // 2. Record the latest GC counts
105             //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 action
114             Stopwatch watch = new Stopwatch();
115             watch.Start();
116             long ticksFst = GetCurrentThreadTimes(); //100 nanosecond one tick
117             for (int i = 0; i < iteration; i++) action.Action();
118             long ticks = GetCurrentThreadTimes() - ticksFst;
119             watch.Stop();
120 
121             // 4. Print CPU
122             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 GC
133             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/jjg0519/p/8309590.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/284432.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

聊聊 C++ 中的几种智能指针(下)

一&#xff1a;背景 上一篇我们聊到了C 的 auto_ptr &#xff0c;有朋友说已经在 C 17 中被弃用了&#xff0c;感谢朋友提醒&#xff0c;今天我们来聊一下 C 11 中引入的几个智能指针。unique_ptrshared_ptrweak_ptr看看它们都怎么玩。二&#xff1a;三大智能指针详解 1. uniq…

iOS回顾笔记( 02 ) -- 由九宫格布局引发的一系列“惨案”

iOS回顾笔记&#xff08; 02 &#xff09; -- 由九宫格布局引发的一系列“惨案” 前言&#xff08;扯几句淡先&#xff09; 回顾到学习UI过程中的九宫格布局时&#xff0c;发现当时学的东西真是不少。 这个阶段最大的特点就是&#xff1a;知识点繁多且琐碎。 我们的目标就是要将…

【GlobalMapper精品教程】007:如何加载谷歌卫星影像?

“Global Mapper支持所有OGC标准数据源类型,例如用于流式栅格地图的WMS / WMTS,用于矢量数据集的WFS和用于为指定区域下载单个数据文件的WCS。预先切片的图像和地形数据集也可以使用OSM(OpenStreetMaps)、TMS(Tiled Map Service)和Google Maps瓦片架构支持。您只需要选择适当…

Mysql清空表(truncate)与删除表中数据(delete)的区别

2019独角兽企业重金招聘Python工程师标准>>> 为某基于wordpress搭建的博客长久未除草&#xff0c;某天升级的时候发现已经被插入了几万条垃圾留言&#xff0c;如果一条条删除那可真是累人的活。遂考虑直接进入mysql直接清空表或者删除表中数据。 本文记录一下这2种操…

[转]云原生到底是什么?

&#x1f4cb; 个人简介 &#x1f496; 作者简介&#xff1a;大家好&#xff0c;我是阿牛&#x1f61c; &#x1f4dd; 个人主页&#xff1a;馆主阿牛&#x1f525; &#x1f389; 支持我&#xff1a;点赞&#x1f44d;收藏⭐️留言&#x1f4dd; &#x1f4ac;格言&#xf…

膛目结舌的代码技巧!一看就是冷暴力~~~~

你见过哪些令你膛目结舌的代码技巧&#xff1f; 代码世界有很多令人大呼小叫的技巧&#xff01;有的代码像魔术师一样巧妙地隐藏了自己&#xff0c;有的像魔法师一样让你眼花缭乱&#xff0c;还有的像瑜伽大师一样灵活自如。它们让我们惊叹不已&#xff0c;让我们觉得自己仿佛置…

联合线程

联合线程实际上就是把多线程又联合成了一个线程&#xff0c;但这里还是要比单线程灵活很多&#xff0c;比如说&#xff0c;我可以让一个线程到运行到某一个条件再联合其他线程。当前线程与其他线程联合在一起&#xff0c;又一种让出cpu&#xff0c;而且直到别个线程运行完&…

Kafka学习征途:不再依赖ZK的KRaft

【Kafka】| 总结/Edison Zhou1新的KRaft架构在Kafka 2.8之前&#xff0c;Kafka重度依赖于Zookeeper集群做元数据管理和集群的高可用&#xff08;即所谓的共识服务&#xff09;。在Kafka 2.8之后&#xff0c;引入了基于Raft协议的KRaft模式&#xff0c;支持取消对Zookeeper的依赖…

探索java世界中的日志奥秘

java日志简单介绍 对于一个应用程序来说日志记录是必不可少的一部分。线上问题追踪&#xff0c;基于日志的业务逻辑统计分析等都离不日志。JAVA领域存在多种日志框架&#xff0c;目前常用的日志框架包括Log4j&#xff0c;Log4j 2&#xff0c;Commons Logging&#xff0c;Slf4j&…

RabbitMQ细说之开篇

前言关于消息中间件的应用场景&#xff0c;小伙伴们应该都耳熟能详了吧&#xff0c;比如经常提到的削峰填谷、分布式事务、异步业务处理、大数据分析等等&#xff0c;分布式消息队列成为其中比较关键的桥梁&#xff0c;也就意味着小伙伴们得掌握相关技能&#xff1b;当下相对比…

【Java】五种常见排序之-----------冒泡排序

冒泡排序&#xff1a; 原理: 将关键字较小的值不断地上浮&#xff0c;将关键字值较大的不断下沉&#xff1b;时间复杂度&#xff1a;O(n^2)空间复杂度&#xff1a;最优&#xff08;即已经排好序&#xff09;为0&#xff0c;平均空间复杂度为O(1);核心代码&#xff1a;for(int i…

混战的低代码江湖,如何区分「李逵」和「李鬼」?

作者&#xff1a;APICloud 创始人刘鑫 这两年&#xff0c;无论是资本层面&#xff0c;还是企业IT部门的关注&#xff0c;“低代码”都是绝对的热点。互联网圈也似在一夜之间冒出了各种各样的低代码公司。 到底什么是低代码&#xff1f;低代码是新技术么&#xff1f;低代码开发能…

关于捕获键盘信息的processDialogkey方法2--具体应用

自定义控件里的keydown方法无法捕获所有的按键消息的处理方法1&#xff08;自定义控件里的keydown方法无法获取的键值如上下左右键等&#xff09; 处理办法具体如下&#xff1a; 1、首先在自定义控件UserControl1中重写ProcessDialogKey方法 自定义控件UserControl1中重写Proce…

指针

指针 题目一&#xff1a; 计算两数的和与差 本题要求实现一个计算输入的两数的和与差的简单函数。 函数接口定义&#xff1a; void sum_diff( float op1, float op2, float psum, float pdiff ); 其中op1和op2是输入的两个实数&#xff0c;psum和pdiff是计算得出的和与差。 裁判…

【MapGIS精品教程】006:MapGIS根据经纬度计算各比例尺图幅编号

己知某点的经纬度或图幅西南图廓点的经纬度,计算该点所在图幅号。 例题一:某点的经度为11433′45″,纬度为3922′30″,计算所在1:250000图幅的编号。 文章目录 1. 公式计算编号的方法2. 软件计算编号的方法1. 公式计算编号的方法 求解过程: 第一步,利用下列公式计算其所…

分析完百年飞机空难数据,我发现了这几条“保命”小秘诀

来 源&#xff5c;Giao数据 数 据 | YaJie 文 章 | 张子豪,YaJie 本文爬取了飞机失事网1908-2020年空难相关数据&#xff0c;包括空难发生次数、机组和乘客的死亡人数与死亡率、不同季节的空难发生次数、空难相关文本的关键词、空难高发地、空难高发航空公司、空难高发机型以…

用 QuestPDF操作生成PDF更快更高效!

QuestPDFQuestPDF是一个开源的工具库&#xff0c;可以在.NET或者.Net Core中生成pdf文档它提供了一个布局引擎&#xff0c;设计时考虑到了完整的分页支持以及灵活性要求&#xff01;比市面上常见的Aspose和iTextSharp好用太多了&#xff01;GitHub地址安装Install-Package Ques…

ASP.NET vs MVC vs WebForms

许多ASP.NET开发人员开始接触MVC认为MVC与ASP.NET完全没有关系&#xff0c;是一个全新的Web开发&#xff0c;事实上ASP.NET是创建WEB应用的框架而MVC是能够用更好的方法来组织并管理代码的一种更高级架构体系&#xff0c;所以可以称之为ASP.NET MVC。 我们可将原来的ASP.NET称为…

在Blazor 中自定义权限验证

Blazor是什么Blazor 是微软在 .NET 里推出的一个 WEB 客户端 UI 交互的框架&#xff0c;使用 Blazor 你可以代替 JavaScript 来实现自己的页面交互逻辑&#xff0c;可以很大程度上进行 C# 代码的复用&#xff0c;Blazor 对于 .NET 开发人员来说是一个不错的选择。需求背景其实我…

【ArcGIS微课1000例】0035:地图面状符号设计教程

地图符号是表示地图内容的基本手段,它由形状不同、大小不一、色彩有别的图形和文字组成。 地图符号是地图的语言,是一种图形语言。它与文字语言相比较,最大的特点是形象直观,一目了然。 本文讲解ArcGIS中面状符号设计方法。 文章目录 一、新建符号样式二、面状符号设计1. 斜…