Hello World
Spiga

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

2009-03-10 09:03 by 老赵, 36635 visits

有数据,有真相,相信大家在平时的工作或学习过程中,都需要比较几种不同方法或实现之间的性能差距。在这些时候,往往就需要我们不断地创建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();

Time方法接受三个参数,名称,循环次数以及需要执行的方法体。打印出花费时间,消耗的CPU时钟周期,以及各代垃圾收集的回收次数。具体实现分几个步骤,如下:

  1. 保留当前控制台前景色,并使用黄色输出名称参数。
  2. 强制GC进行收集,并记录目前各代已经收集的次数。
  3. 执行代码,记录下消耗的时间及CPU时钟周期1
  4. 恢复控制台默认前景色,并打印出消耗时间及CPU时钟周期。
  5. 打印执行过程中各代垃圾收集回收次数。

与传统计数方法相比,这段代码还输出了更多信息:CPU时钟周期及各代垃圾收集回收次数。CPU时钟周期是性能计数中的辅助参考,说明CPU分配了多少时间片给这段方法来执行,它和消耗时间并没有必然联系。例如Thread.Sleep方法会让CPU暂时停止对当前线程的“供给”,这样虽然消耗了时间,但是节省了CPU时钟周期:

CodeTimer.Time("Thread Sleep", 1, () => { Thread.Sleep(3000); });
CodeTimer.Time("Empty Method", 10000000, () => { });

结果如下:

而垃圾收集次数的统计,即直观地反应了方法资源分配(消耗)的规模:

int iteration = 100 * 1000;

string s = "";
CodeTimer.Time("String Concat", iteration, () => { s += "a"; });

StringBuilder sb = new StringBuilder();
CodeTimer.Time("StringBuilder", iteration, () => { sb.Append("a"); });

结果如下:

老赵最近在研究一个问题的几种不同做法在性能上的优劣,其中CodeTimer起到了很重要的作用——这边也先卖个关子,接下来老赵也将会写几篇文章来讲解这个问题。

 

注1:统计CPU时钟周期时使用P/Invoke访问QueryThreadCycleTime函数,这是Vista和Server 2008中新的函数。感谢装配脑袋在这里提供的帮助。

注2:对于.NET 2.0及Vista以下操作系统,请参考《对老赵写的简单性能计数器的修改

Creative Commons License

本文基于署名 2.5 中国大陆许可协议发布,欢迎转载,演绎或用于商业目的,但是必须保留本文的署名赵劼(包含链接),具体操作方式可参考此处。如您有任何疑问或者授权方面的协商,请给我留言

Add your comment

78 条回复

  1. TerryLee
    *.*.*.*
    链接

    TerryLee 2009-03-10 00:41:00

    嗯嗯,这个CodeTimer虽然小,却有大用途,赞一个,呵呵 :)

  2. 老赵
    admin
    链接

    老赵 2009-03-10 00:43:00

    @TerryLee
    饿了,唉……

  3. cs1[未注册用户]
    *.*.*.*
    链接

    cs1[未注册用户] 2009-03-10 01:37:00

    .net委托的性能好吗?可以用这个计算吗?

    大量使用委托合理吗?

  4. eaglet
    *.*.*.*
    链接

    eaglet 2009-03-10 07:07:00

    好东西,不过XP 和 windows server 2003 下是否不能用 QueryThreadCycleTime 这个API?
    通过获取线程时间来统计线程的CPU占有率似乎兼容性更好一些。

  5. Anders Liu
    *.*.*.*
    链接

    Anders Liu 2009-03-10 07:34:00

    果然写出来了,强

  6. 阿牛
    *.*.*.*
    链接

    阿牛 2009-03-10 08:14:00

    真是不错,赞一个。

  7. kkun
    *.*.*.*
    链接

    kkun 2009-03-10 08:27:00

    先标记,慢慢消化

  8. 温景良(Jason)
    *.*.*.*
    链接

    温景良(Jason) 2009-03-10 08:28:00

    不太懂用法!!!!

  9. 1-2-3
    *.*.*.*
    链接

    1-2-3 2009-03-10 08:43:00

    好东西,收藏了。

  10. 张蒙蒙
    *.*.*.*
    链接

    张蒙蒙 2009-03-10 08:48:00

    jz记忆惊人。

  11. 第一控制.NET
    *.*.*.*
    链接

    第一控制.NET 2009-03-10 08:50:00

    追求效率。忽略性能。。

  12. 老赵
    admin
    链接

    老赵 2009-03-10 09:03:00

    --引用--------------------------------------------------
    cs1: .net委托的性能好吗?可以用这个计算吗?

    大量使用委托合理吗?
    --------------------------------------------------------
    委托调用性能和普通方法调用性能相差无几。

  13. 老赵
    admin
    链接

    老赵 2009-03-10 09:05:00

    --引用--------------------------------------------------
    第一控制.NET: 追求效率。忽略性能。。
    --------------------------------------------------------
    追求开发效率?
    其实如果能够在平时积累出性能更好的做法,开发时也不会影响效率的。影响效率的是平时不准备。

  14. 老赵
    admin
    链接

    老赵 2009-03-10 09:05:00

    --引用--------------------------------------------------
    张蒙蒙: jz记忆惊人。
    --------------------------------------------------------
    没有记住他的实现方式,自己写的。

  15. 老赵
    admin
    链接

    老赵 2009-03-10 09:06:00

    --引用--------------------------------------------------
    温景良(Jason): 不太懂用法!!!!
    --------------------------------------------------------
    都有示例了还不懂?

  16. 老赵
    admin
    链接

    老赵 2009-03-10 09:06:00

    --引用--------------------------------------------------
    eaglet: 好东西,不过XP 和 windows server 2003 下是否不能用 QueryThreadCycleTime 这个API?
    通过获取线程时间来统计线程的CPU占有率似乎兼容性更好一些。
    --------------------------------------------------------
    嗯,不能用QueryThreadCycleTime,不如你补充一个?:)

  17. 重典
    *.*.*.*
    链接

    重典 2009-03-10 09:10:00

    快枪果然快。。。

    在做比对时的确这样比较好。。。。做成模板 脑袋就是强人,让人没话说

  18. 老赵
    admin
    链接

    老赵 2009-03-10 09:14:00

    --引用--------------------------------------------------
    重典: 快枪果然快。。。

    在做比对时的确这样比较好。。。。做成模板

    脑袋就是强人,让人没话说
    --------------------------------------------------------
    知道nb的关键是啥了不?是要装配脑袋!

  19. GuoYong.Che
    *.*.*.*
    链接

    GuoYong.Che 2009-03-10 09:20:00

    随便问老赵一句题外话,ASP.NET MVC正式版啥时候出来

  20. xjb
    *.*.*.*
    链接

    xjb 2009-03-10 09:21:00

    还是老赵强,找不到自己写

  21. 老赵
    admin
    链接

    老赵 2009-03-10 09:23:00

    @GuoYong.Che
    不知道

  22. Fans[未注册用户]
    *.*.*.*
    链接

    Fans[未注册用户] 2009-03-10 09:23:00

    int count = GC.CollectionCount(i) - gcCounts[i];
    这个是不是算初始回收一次后又回收了多少次?但GC的回收时机不是无法控制么?有没有可能在此时并没有进行回收呢(内存超大)?

  23. 老赵
    admin
    链接

    老赵 2009-03-10 09:23:00

    --引用--------------------------------------------------
    xjb: 还是老赵强,找不到自己写
    --------------------------------------------------------
    那么简单的东西当然可以自己写。

  24. 老赵
    admin
    链接

    老赵 2009-03-10 09:24:00

    --引用--------------------------------------------------
    Fans: int count = GC.CollectionCount(i) - gcCounts[i];
    这个是不是算初始回收一次后又回收了多少次?但GC的回收时机不是无法控制么?有没有可能在此时并没有进行回收呢(内存超大)?
    --------------------------------------------------------
    没错。不过我们不用控制它,我们进行“比较”就可以了。
    当然可能一次都不回收,不过这是因为没有分配多少东西,和内存大小无关。收集与否只和分配了多少东西有关。

  25. kyorry
    *.*.*.*
    链接

    kyorry 2009-03-10 09:26:00

    我把这篇文章看完,登陆,回复的时候,已经很长很长的回复了,老赵的人气太高了

  26. 蛙蛙池塘
    *.*.*.*
    链接

    蛙蛙池塘 2009-03-10 09:28:00

    收了。

  27. 重典
    *.*.*.*
    链接

    重典 2009-03-10 09:30:00

    @Jeffrey Zhao
    NB是 拆脑袋装脑袋。。。。一系列的过程完成后

  28. 老赵
    admin
    链接

    老赵 2009-03-10 09:36:00

    --引用--------------------------------------------------
    重典: @Jeffrey Zhao
    NB是 拆脑袋装脑袋。。。。一系列的过程完成后
    --------------------------------------------------------
    要像他请教拆装的过程

  29. 老赵
    admin
    链接

    老赵 2009-03-10 09:36:00

    --引用--------------------------------------------------
    kyorry: 我把这篇文章看完,登陆,回复的时候,已经很长很长的回复了,老赵的人气太高了
    --------------------------------------------------------
    谢谢大家支持……

  30. 蛙蛙池塘
    *.*.*.*
    链接

    蛙蛙池塘 2009-03-10 09:37:00

    [DllImport("kernel32.dll")]
    [return: MarshalAs(UnmanagedType.Bool)]
    static extern bool QueryThreadCycleTime(IntPtr threadHandle, ref ulong cycleTime);


    这段儿编译不过去,第二行的中括号有错误,发现老赵老用c# 3.0语法呀,看不懂。

  31. Figo Yang
    *.*.*.*
    链接

    Figo Yang 2009-03-10 09:38:00

    呵呵,那天看ritcher讲这个,我也在想到底那个codetimer是怎么实现的。。哈哈,多谢老赵分享

  32. 蛙蛙池塘
    *.*.*.*
    链接

    蛙蛙池塘 2009-03-10 09:46:00

    无法在 DLL“kernel32.dll”中找到名为“QueryThreadCycleTime”的入口点。

  33. Anytao
    *.*.*.*
    链接

    Anytao 2009-03-10 09:52:00

    @蛙蛙池塘

    QueryThreadCycleTime Function

    Minimum supported client Windows Vista
    Minimum supported server Windows Server 2008
    Header Winbase.h (include Windows.h)
    Library Kernel32.lib
    DLL Kernel32.dll

  34. ziqiu.zhang
    *.*.*.*
    链接

    ziqiu.zhang 2009-03-10 09:56:00

    武林至尊,宝刀JZ.
    脑袋不出,谁与争锋.

  35. 银河
    *.*.*.*
    链接

    银河 2009-03-10 10:04:00

    好文章。
    老赵出手果然不同凡响。

  36. 汗津津
    *.*.*.*
    链接

    汗津津 2009-03-10 10:46:00

    --引用--------------------------------------------------
    蛙蛙池塘: 收了。
    --------------------------------------------------------

  37. 暗香浮动
    *.*.*.*
    链接

    暗香浮动 2009-03-10 11:09:00

    不错的功能.
    让数据说话.

  38. 流牛木马
    *.*.*.*
    链接

    流牛木马 2009-03-10 12:01:00

    老赵同志很牛X

  39. Angel Lucifer
    *.*.*.*
    链接

    Angel Lucifer 2009-03-10 13:08:00

    请老赵仔细考虑并行程序的可能性,呵呵。

  40. lovecherry
    *.*.*.*
    链接

    lovecherry 2009-03-10 14:00:00

    思路那是相当清晰:)

  41. 老赵
    admin
    链接

    老赵 2009-03-10 14:11:00

    --引用--------------------------------------------------
    Angel Lucifer: 请老赵仔细考虑并行程序的可能性,呵呵。
    --------------------------------------------------------
    大哥你的思维僵化了,不要到处想着并行嘛,本来是多简单的一段测试代码……就像上次看到“强类型”就一定要从语言实现角度来分析,没有必要,没有必要……
    不过很明显我这个是不考虑并行程序的,只是简单地用来测试一小段实现的时间——例如用iteration这个用来循环n次,明显只是为了不断的累积次数而已,呵呵。
    真要说并行程序的话……其实也就CPU Cycles没有参考价值,其他还是一样的,恩恩。

  42. jantouy
    *.*.*.*
    链接

    jantouy 2009-03-10 14:41:00

    很强大,虽然没有多懂,但还是很佩服,学习了

  43. 文明的天空
    *.*.*.*
    链接

    文明的天空 2009-03-10 15:45:00

    赵哥的东西总是让我回味无穷!
    爬在地上顶一下!

  44. mikelij
    *.*.*.*
    链接

    mikelij 2009-03-10 15:53:00

    用Performance counter也可以

  45. 老赵
    admin
    链接

    老赵 2009-03-10 15:54:00

    @mikelij
    Performance Counter一般是基于采样的,这里是精确统计。

  46. XP SP4听说要来了[未注册用户]
    *.*.*.*
    链接

    XP SP4听说要来了[未注册用户] 2009-03-10 16:21:00

    QueryThreadCycleTime和QueryPerformanceCounter怎么对比?

    另:GC是整个.NET CLR下的一个公用的GC,如果有多个.NET程序在运行的时候,如何保证得到的垃圾数量是当前域的?

  47. 老赵
    admin
    链接

    老赵 2009-03-10 16:52:00

    @XP SP4听说要来了
    GC统计的是系统中所有的CLR应用程序?我不清楚。
    如果是的话,那么就不要让别的程序来干扰便是。本来就是开发环境下的简单统计,这个代码够用了。

  48. !A.Z[未注册用户]
    *.*.*.*
    链接

    !A.Z[未注册用户] 2009-03-10 17:35:00

    GC针对的是当前的CLR Host.

  49. 老赵
    admin
    链接

    老赵 2009-03-10 17:52:00

    --引用--------------------------------------------------
    !A.Z: GC针对的是当前的CLR Host.
    --------------------------------------------------------
    嗯嗯,那么就没有问题了。

  50. 杨同学
    *.*.*.*
    链接

    杨同学 2009-03-10 18:25:00

    wow, it's really usefull !

  51. mikelij
    *.*.*.*
    链接

    mikelij 2009-03-10 19:38:00

    @Jeffrey Zhao
    --引用--------------------------------------------------
    Jeffrey Zhao: @mikelij
    Performance Counter一般是基于采样的,这里是精确统计。
    --------------------------------------------------------
    Performance Counter可以用来计时的,它有四种模式.
    看你要精确到何程度了. 毫秒级的话,办法多的是, 比如gettickaccount, 微秒级的话可以用queryperformancecounter, 纳秒级的话只能利用CPU内部的频率了.还得看具体的CPU有多快. 除非特别必要,最好不搞纳秒级.呵

  52. 老赵
    admin
    链接

    老赵 2009-03-10 19:47:00

    @mikelij
    Performance Counter的作用在于采样数据,用它来计时的好处在哪里呢?总归是Stopwatch了。

  53. mikelij
    *.*.*.*
    链接

    mikelij 2009-03-10 20:09:00

    @Jeffrey Zhao
    那些工业化的测试软件都用Performance counter, 这些测试软件还可以根据Performance counter里面的数据产生专业的报表. 我们自己写的工具相对没有那些工具软件标准.

  54. mikelij
    *.*.*.*
    链接

    mikelij 2009-03-10 20:20:00

    @Jeffrey Zhao
    Performance counter四种常用模式:
    NumberOfItems32 - a counter that counts the number of items. You can use it to calculate how often an operation was performed or to count the total number of items you processed.
    RateOfCountsPerSecond32 - a counter that tracks down the number of items or operations per second.
    AverageTimer32 - a counter that measures the average time required to perform an operation. The counter is calculated by the ratio of the total time elapsed and the number of items completed during that time. This comes along with ...
    AverageBase - the base counter for AverageTimer32 which counts the number of items completed during the elapsed time.
    它是同样的操作多运行几次, 取平均. 对于测试来说,这样比较准确点.

  55. Kevin-moon
    *.*.*.*
    链接

    Kevin-moon 2009-03-10 21:06:00

    什么都不说了 很喜欢

  56. 老赵
    admin
    链接

    老赵 2009-03-10 21:57:00

    --引用--------------------------------------------------
    mikelij: @Jeffrey Zhao
    那些工业化的测试软件都用Performance counter, 这些测试软件还可以根据Performance counter里面的数据产生专业的报表. 我们自己写的工具相对没有那些工具软件标准.
    --------------------------------------------------------
    您说的是事实,我也没有说您错,可惜您对于需要解决的问题没有太大意义,这是关键所在。
    剩下的不多说了,文章从一开始就谈过这个方法的目标是什么了,呵呵。
    不过还是谢谢您提供的资料。:)

  57. mikelij
    *.*.*.*
    链接

    mikelij 2009-03-10 22:38:00

    @Jeffrey Zhao
    Very nice. 多交流. 特别是如果有什么见解, 请务必在我那里留下你的Precious Comments. Thank you very much!

  58. G yc {Son of VB.NET}
    *.*.*.*
    链接

    G yc {Son of VB.NET} 2009-03-10 23:08:00

    呵呵,
    出品速度很快啊~~

  59. 老赵
    admin
    链接

    老赵 2009-03-11 01:12:00

    --引用--------------------------------------------------
    G yc {Son of VB.NET}: 呵呵,
    出品速度很快啊~~
    --------------------------------------------------------
    很简单的东西啊,正好用到了。

  60. 张荣华
    *.*.*.*
    链接

    张荣华 2009-03-11 09:22:00

    “ Jeffrey Richter大叔在Keynote Session中进行了一个名为“The Performance of Everyday Things”的主题演讲 “
    老赵 这个有没有PPT之类的东西 ,可以共享啊?

  61. wang22[未注册用户]
    *.*.*.*
    链接

    wang22[未注册用户] 2009-03-11 10:32:00

    JR的版本在这:
    http://conference.softcompass.com/net2009/record/ppt/Jeffrey Richter-Performance of Every Day Things Code.zip

  62. 没剑
    *.*.*.*
    链接

    没剑 2009-03-11 12:02:00

    不错哗,偶拿来用用啦,谢谢老赵啊~

  63. 空气
    *.*.*.*
    链接

    空气 2009-03-11 22:34:00

    VS有个自带的性能测试工具

  64. 老赵
    admin
    链接

    老赵 2009-03-11 22:36:00

    @空气
    如果您能够先看文章再回复我会很感激的,呵呵。

  65. lpzyz[未注册用户]
    *.*.*.*
    链接

    lpzyz[未注册用户] 2009-03-18 00:05:00

    老赵,你好,请问一下,我自己试了一下你写的这个计数器,出现下面的错误:
    无法在 DLL“kernel32.dll”中找到名为“QueryThreadCycleTime”的入口点。
    请问是什么问题

  66. 老赵
    admin
    链接

    老赵 2009-03-18 00:38:00

    @lpzyz
    QueryThreadCycleTime是Vista和Server 2008上的新函数……其实文章中都已经写了,希望可以仔细看一下,呵呵。

  67. lpzyz[未注册用户]
    *.*.*.*
    链接

    lpzyz[未注册用户] 2009-03-18 10:01:00

    不好意思,没注意看最后的备注,问题已解决,谢谢老赵!回复真是快!

  68. 小糊涂虫
    *.*.*.*
    链接

    小糊涂虫 2009-06-16 00:36:00

    以后要有事没事多看看老赵的文章,感染一下自己

  69. Bill New
    *.*.*.*
    链接

    Bill New 2009-09-08 20:30:00

    老赵,你首页右上角About一栏下面的头像和个人说明是怎么弄的啊,我弄了半天不知道在哪里配置,指点一下吧

  70. 老赵
    admin
    链接

    老赵 2009-09-08 20:42:00

    @Bill New
    就是在公告里写HTML。

  71. Bill New
    *.*.*.*
    链接

    Bill New 2009-09-09 10:19:00

    @Jeffrey Zhao
    谢啦

  72. _lsp[未注册用户]
    *.*.*.*
    链接

    _lsp[未注册用户] 2009-09-28 10:10:00

    老赵, 我有两点看法,请帮忙分析:
    1. 在你的示例代码中看不见对Initialize() 方法的调用,属于书写遗漏吗?当然了我相信在实际应用时你调用了此方法。
    2. 第一次调用CoderTimer.Time()前要调用一次Initialize()去预热。多少显得有些不够完美。可否考虑把Initialize()改成private,然后添加一static constructor? 如下:

    -----------------------------
    static void initialize()
    {}

    static CodeTimer()
    {
    initialize();
    }
    -----------------------------

  73. 老赵
    admin
    链接

    老赵 2009-09-28 10:36:00

    @_lsp
    示例代码只是片断了。因为Initialize是对上下文环境有重大改变,因此我还是打算显式的调用。

  74. e狐
    *.*.*.*
    链接

    e狐 2010-02-07 12:40:00

    赵老师,中间测试性能的太吗我能看懂。。但是为什么强制GC进行收集?那段代码(2、5)是啥作用?

  75. 链接

    tiwlin 2011-07-05 11:57:34

    在JR的CLR VIA里面应该有此方法。

  76. Eye's
    113.204.180.*
    链接

    Eye's 2011-08-27 15:32:06

    int iteration = 2;
    CodeTimer.Time("Test1", iteration, () => { CodeTimer.Time("1", iteration, () => { }); });
    CodeTimer.Time("Test2", iteration, () => { CodeTimer.Time("2", iteration, () => { }); });
    

    Test1:

    1
            Time Elapsed:   0ms
            CPU Cycles:     335,192
            Gen 0:          0
            Gen 1:          0
            Gen 2:          0
    
    1
            Time Elapsed:   0ms
            CPU Cycles:     3,498
            Gen 0:          0
            Gen 1:          0
            Gen 2:          0
    
            Time Elapsed:   6ms
            CPU Cycles:     4,952,211
            Gen 0:          2
            Gen 1:          2
            Gen 2:          2
    

    Test2:

    2
            Time Elapsed:   0ms
            CPU Cycles:     336,732
            Gen 0:          0
            Gen 1:          0
            Gen 2:          0
    
    2
            Time Elapsed:   0ms
            CPU Cycles:     3,949
            Gen 0:          0
            Gen 1:          0
            Gen 2:          0
    
            Time Elapsed:   15ms
            CPU Cycles:     5,290,648
            Gen 0:          2
            Gen 1:          2
            Gen 2:          2
    

    • 系统: WIN7 32 位
    • cpu: E2210 @ 2.20GHz
    • 内存: 2G

    相差这么大?

  77. 链接

    david.telvent 2012-06-15 19:15:51

    这里可以测试出执行时间,可否测试出“过程中”的内存消耗情况?

  78. 老赵
    admin
    链接

    老赵 2012-06-15 22:02:36

    @david.telvent

    不是有GC次数吗?

发表回复

登录 / 登录并记住我 ,登陆后便可删除或修改已发表的评论 (请注意保留评论内容)

昵称:(必填)

邮箱:(必填,仅用于Gavatar

主页:(可选)

评论内容(大于5个字符):

  1. Your Name yyyy-MM-dd HH:mm:ss

使用Live Messenger联系我