きな粉もち.net

.NET関連仕事に携わっています。OSSのソースを読んで気がついたことを中心に呟いたりブログに投稿したりしています。最近はUiPathを使ったRPAも研究中。気軽にフォローやツッコミよろしくおねがいします! Gitはここを使っています https://github.com/kinakomotitti

C# × ベンチマーク × パフォーマンス解析するためのツールをさがしてみた

この記事の目的

この記事では、
今後使っていくベンチマークツールを決めること
を目的としています。

アジェンダ

  1. ベンチマークツールの選定
  2. System.Diagnostics.PerformanceCounter
  3. Benchmark DotNet
  4. BenchShark

本題

ベンチマークツールの選定

非同期処理のことを調べていると、こう実装すると「パフォーマンスが良い(or悪い)」という言葉をよく目にすることがあります。
そしてその中の大半の記事では、具体的にどの程度のパフォーマンスの違いがあるかについて言及しません。

それではわからない( ゚Д゚)


じゃあ、自分で調べてみたらいいじゃん(/・ω・)/


System.Diagnostics.Stopwatchクラス使ってパフォーマンスを・・・
と思っていたのですが、これだと、処理時間だけしかわからないです。
かといって、ほかにパフォーマンスを計測する手段がない。

そんなこんなで、Nugetでパフォーマンス解析(ベンチマーク)をするためのライブラリを検索してみました。

まずは「パフォーマンス」で検索
f:id:kinakomotitti:20180401231415p:plain

・・・まぁないよね。
次に「ベンチマーク」で検索
f:id:kinakomotitti:20180401231446p:plain


・・・ない。どんどん行きます。
f:id:kinakomotitti:20180401231458p:plain

Microsoftが出しているそれっぽい名前のものがあった!
とりあえず、キープということで・・・
最後は「Benchmark」で検索
f:id:kinakomotitti:20180401231544p:plain

思いのほか、いっぱいあった(*´Д`)
いっぱいあってわからないので、名前が気になるもの2つを候補としました。
・Benchmark DotNet
・BenchShark

★System.Diagnostics.PerformanceCounter

概要:Windowsのパフォーマンスカウンターにアクセスする機能を提供するクラスです。
パフォーマンスモニターの値を使った処理を実装する際に使うクラスの様です。
これはこれで気になりますが、今回の目的のブツではないようです。

PerformanceCounter クラス (System.Diagnostics)

★Benchmark DotNet

概要:ベンチマークのための強力な.NETライブラリ
公開日:2018年3月2日 (2018/03/02)
Home - BenchmarkDotNet Documentation

実際にやってみた手順を残しておきます
Step0)コンソールアプリを作成
Step1)Nugetでライブラリを取得
Step2)サンプルプログラム実装

	    [HtmlExporter]
	    public class Log4netTester ←パフォーマンス計測対象クラス
	    {
	        private static ILog logger = LogManager.GetLogger("kinakomotitti");
	
	        [Benchmark]
	        public void Test01() ←パフォーマンス計測対象メソッド
	        {
	            logger.Debug("Test");
	        }
	
	        [Benchmark]
	        public void Test02() ←パフォーマンス計測対象メソッド
	        {
	            //no process
	        }
	    }
	    public class Program
	    {
	        public static void Main(string[] args)
	        {
	   //計測処理
	            var summary = BenchmarkRunner.Run<Log4netTester>();
	        }
	    }
	


Step3)Releaseビルドの作成 ※デバッグビルドでは結果が計測されません
Step4)実行
Step5)結果の確認
Releaseビルドの実行ディレクトリに結果ディレクトリが自動で作成されます。
f:id:kinakomotitti:20180402221126p:plain
カタツムリでは、いろいろな出力形式を提供してくれています。
今回は、HTML形式で出してみました。
f:id:kinakomotitti:20180402221133p:plain
パソコンのスペックまで出してくれるあたり便利ですねw
計測も複数回にわたって処理を実行し、その平均を求めてくれるました。
Stopwatchつかって一回実行して「パフォーマンスガー」って言ってた自分が恥ずかしいです。。。

もう、パフォーマンス計測は一生これを使っていこうとすら思うくらいのツールだと思いました。

★BenchShark

概要:.NETアプリケーションのベンチマークパフォーマンスのための軽量ライブラリ。 BenchSharkは、コード内のボトルネックを追跡するために、機能の速度を評価するための強力で使いやすいAPIを提供します。
公開日:2013年11月19日 (2013/11/19)
wiresharkとにた名前だったので、ピックアップしてみました。
5年前にリリースされたものだったのですね。
こちらも使い方の簡単メモを残してみます。
Step0)コンソールアプリケーションを作成する
Step1)NugetでBenchSharkをインストールする
Step2)計測コードを実装する(カタツムリサンプルに追記しました。)

	    [HtmlExporter]
	    public class Log4netTester
	    {
	        private static ILog logger = LogManager.GetLogger("kinakomotitti");
	
	        [Benchmark]
	        public void Test01()
	        {
	            logger.Debug("Test");
	        }
	
	        [Benchmark]
	        public void Test02()
	        {
	            //no process
	        }
	    }
	    public class Program
	    {
	        public static void Main(string[] args)
	        {
	            //KataTsumuri
	            //var summary = BenchmarkRunner.Run<Log4netTester>();
	            var tester = new Log4netTester();
	            var shark = new BenchShark();
	            // Evaluate the function with 100 iterations
	            var result = shark.EvaluateTask(tester.Test01, 1000);
	            Console.WriteLine("Total elapsed: {0} milliseconds / {1} ticks", result.TotalExecutionTime, result.TotalElapsedTicks);
	            Console.WriteLine("Average elapsed: {0} milliseconds / {1} ticks", result.AverageExecutionTime, result.AverageElapsedTicks);
	             result = shark.EvaluateTask(tester.Test01, 1000);
	            Console.WriteLine("Total elapsed: {0} milliseconds / {1} ticks", result.TotalExecutionTime, result.TotalElapsedTicks);
	            Console.WriteLine("Average elapsed: {0} milliseconds / {1} ticks", result.AverageExecutionTime, result.AverageElapsedTicks);
	            Console.ReadKey();
	        }
	    }

Step3)実行&計測結果確認
f:id:kinakomotitti:20180402221150p:plain
サメツールでは、Action型の引数と、イテレーションを引数で指定して実行することができます。
メソッドやクラスに属性を付与せずに簡単に計測を開始できるのが素敵だと思いました。
結果も自分の好きなフォーマットで出力できるので、オリジナルライブラリにラップするのも簡単にできそうです。

まとめ

今回はベンチマークツールとして、Benchmark DotNetBenchSharkの2つの概要をざっくり見てみました。
どちらも使い勝手が良くて素敵だと思います。
どちらも使っていきたいですが、今後はBenchmark DotNetを使っていこうと思います。
(公開日、出力ファイル形式、を考慮しました。)
本格的に使い始める前に、もう少し使い方を研究していこうと思います。