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

有数据,有真相,相信大家在平时的工作或学习过程中,都需要比较几种不同方法或实现之间的性能 差距。在这些时候,往往就需要我们不断地创建Stopwatch,打开,关闭,然后打印时间。这种一遍又一 遍的重复终有一天会让人忍无可忍,因此如果能有一个“标准”的性能计数器,那应该可以让生活轻松许 多。这个性能计数器不用复杂,够用就好;也不需要考虑扩展性,要扩展时直接修改代码就够了;同样不 需要考虑输出格式,直接打印在Console就行。

在上次的.NET技术大会中,Jeffrey Richter大叔在Keynote Session中进行了一个名为“The Performance of Everyday Things”的主题演讲,展示了各种常用编程元素之间的性能对比。在演示中他 使用了一个名为CodeTimer的简单计数器,用于统计每种做法的性能。可惜翻遍了每个地方都没发现JR大 叔在哪里公开了这个计数器的实现。算了,那么就凭着印象写一个出来吧,反正也不复杂。

总的来说,CodeTimer有两个公开方法,一个是Initialize,一个是Time:

public static class CodeTimer
{
  public static void Initialize()
  {
    Process.GetCurrentProcess().PriorityClass =  ProcessPriorityClass.High;
    Thread.CurrentThread.Priority =  ThreadPriority.Highest;
    Time("", 1, () => { });
  }

   public static void Time(string name, int iteration, Action action)
  {
     ...
  }
}

CodeTimer.Initialize方法应该在测试开始前调用。首先它会把当前进程及当前线程的优先级设为最 高,这样便可以相对减少操作系统在调度上造成的干扰。然后调用一次Time方法进行“预热”,让JIT将 IL编译成本地代码,让Time方法尽快“进入状态”。Time方法则是真正用于性能计数的方法,实现如下:

public static void Time(string name, int iteration, Action action)
{
if (String.IsNullOrEmpty(name)) return;
// 1.
ConsoleColor currentForeColor = Console.ForegroundColor;
Console.ForegroundColor = ConsoleColor.Yellow;
Console.WriteLine(name);
// 2.
GC.Collect(GC.MaxGeneration, GCCollectionMode.Forced);
int[] gcCounts = new int[GC.MaxGeneration + 1];
for (int i = 0; i <= GC.MaxGeneration; i++)
{
gcCounts[i] = GC.CollectionCount(i);
}
// 3.
Stopwatch watch = new Stopwatch();
watch.Start();
ulong cycleCount = GetCycleCount();
for (int i = 0; i < iteration; i++) action();
ulong cpuCycles = GetCycleCount() - cycleCount;
watch.Stop();
// 4.
Console.ForegroundColor = currentForeColor;
Console.WriteLine("\tTime Elapsed:\t" + watch.ElapsedMilliseconds.ToString ("N0") + "ms");
Console.WriteLine("\tCPU Cycles:\t" + cpuCycles.ToString("N0"));
// 5.
for (int i = 0; i <= GC.MaxGeneration; i++)
{
int count = GC.CollectionCount(i) - gcCounts[i];
Console.WriteLine("\tGen " + i + ": \t\t" + count);
}
Console.WriteLine();
}
private static ulong GetCycleCount()
{
ulong cycleCount = 0;
QueryThreadCycleTime(GetCurrentThread(), ref cycleCount);
return cycleCount;
}
[DllImport("kernel32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
static extern bool QueryThreadCycleTime(IntPtr threadHandle, ref ulong cycleTime);
[DllImport("kernel32.dll")]
static extern IntPtr GetCurrentThread();

时间: 2025-01-19 09:25:33

一个简单的性能计数器:CodeTimer的相关文章

插件系统中跨域调用的性能和“一个简单的性能计数器”的使用

系统大概的流程如下:从数据中心接收到数据包(1万~3万(个)/秒,使用WCF)可以被不同的应用场景使 用,每个应用场景的业务逻辑各不相同,而每个场景的接收数据包部分的代码是相同的,于是使用一个容 器将所有的"应用场景的dll"通过反射加载,同时容器接收所有的数据包并把他们分发给"应用场景的dll" ,接收数据的功能,自然被抽象成了Interface.透彻一点讲就是一个插件系统,只不过这个插件有点儿 大而已,大到整个系统都是个插件.这个容器我们暂时叫他"引擎

介绍一个简单的推广方案

企业怎样做好网络推广,相对来说企业网站的推广更简单,因为企业有两大优势是其他网站比不了的.一就是企业在线下已经有一定的品牌;二就是企业有自己的产品或者服务.所以针对这两个优势来说,大多数中小企业的网络推广还是比较好做的.以下是守护制作的一个简单的推广方案. 一.企业网络推广想达到什么效果.       对于网络推广来说,大家最关注的就是能达到什么效果,所以在做企业推广的时候我们就应该有一个定位,我们想要达到的效果是什么?是网络品牌或者是成交产品.对于企业网站运营者来说,设定这个目标后完成需要的时

如何使用SQLyogEnt来建立一个简单的数据库

如果你选择PHP进行网站建设,那你必须懂得php建立数据库,那用mysql数据就是必须的了.刚接触php的朋友也许对这个mysql数据库很陌生,但如果有一款非常好用的数据库管理工具,那是用起来就方便多了,笔者几天就向大家介绍一款mysql的管理工具SQLyogEnt,笔者是用的 SQLyogEnt是英文版,目前好像没有中文版,由于功能强大,所以SQLyogEnt很受PHP用户的喜爱,接下就用实例来讲解下如何使用 SQLyogEnt来建立一个简单的数据库. 今天我建立的数据库名叫"mydb&quo

c c++-求用c编写的一个简单的爬虫程序,高手赐教,不胜感激

问题描述 求用c编写的一个简单的爬虫程序,高手赐教,不胜感激 本人是初学者,要编写一爬虫程序,抓取60多万个网页上的信息,实在是无从下手,请高手给一个能看得懂的简单的爬虫程序学习用,多谢 解决方案 我也要写一个C爬虫,不过遇到了一些问题,比如58这样的网站,用getaddrinfo返回的ip无法连接,已经耽误了我好几天了,别的问题到还没遇到

C/C++中一个简单的enum手法(idiom)

今天写程序的时候,又用到这个idiom了,于是顺便贴出来.这个idiom蛮简单的,估计很 多人都用过.今天主要是贴出来给新手参考(老手们就甭费时看此帖了). 为了说明这个手法具体该咋用,咱举一个简单的例子来说事儿.比方说要开发一个网络程 序,其中需要统计各种网络协议的数据包数量. ★版本1 假设一开始只需要处理HTTP和FTP两种协议.有些同学不假思索,立即会声明如下两个整 数用于统计: int nCntHttp = 0; int nCntFtp = 0; 猛一看,似乎没啥问题.但是,如果需求发

如何做一个简单的小网站

如何做一个简单的小网站,请注意:拥有域名不代表你就有了网站.做之前要想一下,网站用来干什么?静态的还是动态的,自己至少要懂一点代码知识,不懂程序的话,也要对html多少了解一些. 不然,我建议你还是到各大网站申请个Blog写日志算了:) 如果你: 1.做个简历式的小网站 上面就放些文章,图片或者资料,且文件不多,那么选择静态空间就搞定.你可以自己或者找人来做个网页的模版,自己套内容就 可以. 整体下来只要99元,包括域名和空间.在http://www.nicenic.com/design/?s=

一个简单的web服务器

写在前面 新的一年了,新的开始,打算重新看一遍asp.net本质论这本书,再重新认识一下,查漏补缺,认认真真的过一遍. 一个简单的web服务器 首先需要引入命名空间: System.Net,关于网络编程的大部分类型及操作都可以在这个命名空间下找到. IPAddress:类用来表示一个ip地址. IPEndPoint:用来表示一个IP地址和一个端口号的组合,称为网络的端点. System.Net.Sockets:命名空间中提供了基于Socket编程的数据类型. Socket类封装了Socket的操

源码-用javaSSH框架做一个简单的登录功能

问题描述 用javaSSH框架做一个简单的登录功能 用SSH框架做一个简单的登录功能,登录成功则跳转到一个页面,登录失败则跳转到一个失败页面,MySQL数据库.求大神指点,最好能提供源码 解决方案 Spring 3.x 企业应用开发实战的第一个例子就符合你的要求了.Mysql+srping3 解决方案二: 告诉我你的扣扣邮箱,我发你邮箱 解决方案三: 主要还是在struts2 里面,处理业务逻辑,再跳转到指定页面,关键在struts,xml配置文件里面

一个简单的数据库查询问题

问题描述 一个简单的数据库查询问题 一个文章表,一个评论表,通过文章的ID关联,现在要查出文章表中的一条数据和评论表中关于这篇文章的评论的个数,求帮忙 谢谢了. 解决方案 select w.*(select count(*) from 评论表 p where p.id=w.id ) as cnt from 文章表 w where w.id="" ""看明白不? 解决方案二: select w.neirong as 内容count(*) as 评论个数 from we