<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12
      代碼改變世界

      一個簡單的性能計數器:CodeTimer

      2009-03-10 09:03  Jeffrey Zhao  閱讀(48303)  評論(77)    收藏  舉報

      有數據,有真相,相信大家在平時的工作或學習過程中,都需要比較幾種不同方法或實現之間的性能差距。在這些時候,往往就需要我們不斷地創建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以下操作系統,請參考《對老趙寫的簡單性能計數器的修改

      主站蜘蛛池模板: 婷婷色爱区综合五月激情韩国| 99久久无码私人网站| 中文字幕日韩有码av| 春菜花亚洲一区二区三区| 少妇人妻真实偷人精品| 69天堂人成无码免费视频| 久久精品国产亚洲av品| 久久久久久久一线毛片| 日韩精品卡1卡2日韩在线| 国产人妻丰满熟妇嗷嗷叫| 国产精品美女免费无遮挡| 亚洲成人av在线高清| 亚洲欧美牲交| 国产不卡精品视频男人的天堂| 欧美韩中文精品有码视频在线| 国产精品一区二区日韩精品| 日本精品极品视频在线| 久久国产精品老女人| 亚洲 自拍 另类小说综合图区| 精品激情视频一区二区三区| 国产欧美日韩精品丝袜高跟鞋| 麻豆国产成人AV在线播放| 色综合网天天综合色中文| 少妇高潮喷水惨叫久久久久电影| 成人中文在线| 麻豆精品一区二正一三区| 亚洲自拍偷拍中文字幕色| av一区二区中文字幕| 中文字幕无码免费久久99| 亚洲av中文一区二区| 国产99久久亚洲综合精品西瓜tv| 中文字幕va一区二区三区| 天台县| www久久只有这里有精品| 亚洲精品欧美综合二区| 久久69国产精品久久69软件| 日本不卡的一区二区三区| 少妇久久久被弄到高潮| 欧洲码亚洲码的区别入口| 日韩国产成人精品视频| 亚洲av永久无码精品网站|