Quantcast
Channel: C#タグが付けられた新着記事 - Qiita
Viewing all articles
Browse latest Browse all 9301

【C#/ASP.NET】Web APIのベンチマークを計測する

$
0
0
概要 クライアントが「Web APIをコールし、サーバから応答を得るまでの時間」を計測した。 具体的には、HttpClientとBenchmarkDotNetを使って、処理時間の集計(平均値・最小値・最大値を算出)し、集計結果をHTMLでエクスポートとした。 計測の手順と実装を掲載する。 動作環境 クライアント .NET Framework4.6.1 Nugetパッケージ  ・BenchmarkDotNet 0.13.0  ・NewtonsoftJson 13.0.1 サーバー ASP.NET Web API .NET Framework4.6.1 計測予定のWebAPIの一覧 今回はGET/PUT/POST/DELETEを準備する。 下記表のWeb APIをサーバ側に実装する(自動生成コードをそのまま利用する)。 HTTPメソッド URL GET http://localhost:19691/api/values POST http://localhost:19691/api/values PUT http://localhost:19691/api/values/{id} DELETE http://localhost:19691/api/values/{id} アプリケーションを作成する。 クライアントを作成する コンソールアプリケーションでソリューションを作成して、下記手順を実行する。 1. BenchmarkDotNetを適用する。 「BenchmarkDotNet」をNugetパッケージでインストールする。 2. 計測対象のメソッドを作成する。 「BenchmarkDotNet」で計測する対象メソッド、その他オプションは「属性」で設定する。 各属性の意味はコメントで補足説明する。 WebApiClient using System.Net.Http; using System.Text; using System.Threading.Tasks; using BenchmarkDotNet.Attributes; using Newtonsoft.Json; namespace BenchMark { [HtmlExporter]//Htmlエクスポート public class WebApiClient { private static readonly HttpClient Client = new HttpClient(); private static string _jsonString; private static StringContent _data; [GlobalSetup]//初回セットアップ public void GlobalSetUp() { _jsonString = JsonConvert.SerializeObject("TestMessage"); _data = new StringContent(_jsonString, Encoding.UTF8, mediaType: "application/json"); } [Benchmark]//計測対象のメソッドに指定 public async Task GetAsync() { var response = await Client.GetAsync("http://localhost:19691/api/values"); response.EnsureSuccessStatusCode(); } [Benchmark] public async Task PutAsync() { var response = await Client.PutAsync("http://localhost:19691/api/values/5", _data); response.EnsureSuccessStatusCode(); } [Benchmark] public async Task PostAsync() { var response = await Client.PostAsync("http://localhost:19691/api/values", _data); response.EnsureSuccessStatusCode(); } [Benchmark] public async Task DeleteAsync() { var response = await Client.DeleteAsync("http://localhost:19691/api/values/5"); response.EnsureSuccessStatusCode(); } } } 3. メイン関数から計測対象をコールする。 Program.cs using System.Threading.Tasks; using BenchmarkDotNet.Running; namespace BenchMark { class Program { static void Main(string[] args) { //CheckOperation().GetAwaiter().GetResult(); //計測を開始する BenchmarkRunner.Run<WebApiClient>(); } /// <summary> /// ベンチマーク測定前の動作確認用 /// </summary> static async Task CheckOperation() { var client = new WebApiClient(); client.GlobalSetUp(); await client.GetAsync(); await client.PutAsync(); await client.PostAsync(); await client.DeleteAsync(); } } } サーバを作成する。 自動生成コード使って、Web APIを準備する。 1. Web アプリケーションでソリューションを作成 Web APIを選ぶ。 2. Web APIが自動生成されたことを確認する。 「ソリューションエクスプローラー」 →「Controllers」   ValuesControllers.csを開く。 ValuesControllers.cs using System; using System.Collections.Generic; using System.Linq; using System.Net; using System.Net.Http; using System.Web.Http; namespace HttpServerBenchMark.Controllers { public class ValuesController : ApiController { // GET api/values public IEnumerable<string> Get() { return new string[] { "value1", "value2" }; } // GET api/values/5 public string Get( int id ) { return "value"; } // POST api/values public void Post( [FromBody]string value ) { } // PUT api/values/5 public void Put( int id, [FromBody]string value ) { } // DELETE api/values/5 public void Delete( int id ) { } } } パフォーマンス計測 1. サーバーを実行する。 2. クライアントを実行する。 ※Releaseビルドで実行すること。 計測が完了することを待つ。 計測開始時のターミナル出力 // Validating benchmarks: // ***** BenchmarkRunner: Start ***** // ***** Found 4 benchmark(s) in total ***** // ***** Building 1 exe(s) in Parallel: Start ***** : : 計測終了時のターミナル出力 // ***** BenchmarkRunner: End ***** // ** Remained 0 benchmark(s) to run ** Run time: 00:01:59 (119.94 sec), executed benchmarks: 4 Global total time: 00:02:02 (122.68 sec), executed benchmarks: 4 3. 集計結果を確認する。 ターミナル出力で「Summary」を探して確認する。 結果サマリーを確認する // * Summary * BenchmarkDotNet=v0.13.0, OS=Windows 10.0.19043.985 (21H1/May2021Update) Intel Core i7-7700HQ CPU 2.80GHz (Kaby Lake), 1 CPU, 8 logical and 4 physical cores [Host] : .NET Framework 4.8 (4.8.4341.0), X86 LegacyJIT DefaultJob : .NET Framework 4.8 (4.8.4341.0), X86 LegacyJIT | Method | Mean | Error | StdDev | Median | |------------ |---------:|----------:|----------:|---------:| | GetAsync | 1.921 ms | 0.1567 ms | 0.4469 ms | 1.749 ms | | PutAsync | 1.495 ms | 0.0319 ms | 0.0926 ms | 1.494 ms | | PostAsync | 1.472 ms | 0.0291 ms | 0.0638 ms | 1.474 ms | | DeleteAsync | 1.281 ms | 0.0256 ms | 0.0455 ms | 1.293 ms | ファイルのExportを確認する。 今回はHTMLファイル出力しているため、ターミナルでExport先を確認する。 // ***** BenchmarkRunner: Finish ***** // * Export * BenchmarkDotNet.Artifacts\results\BenchMark.WebApiClient-report.csv BenchmarkDotNet.Artifacts\results\BenchMark.WebApiClient-report-github.md BenchmarkDotNet.Artifacts\results\BenchMark.WebApiClient-report.html ファイルエクスプローラで下記パスに移動する。 ソリューションのパス\bin\Release\BenchmarkDotNet.Artifacts 下記画像のファイルが存在する。 「BenchMark.WebApiClient-20210606-231210.log(※)」に、ターミナル出力と同様の内容が記録されている。 ※ソリューション名-クラス名-実行日時.logって命名の様子。 ソリューションのパス\bin\Release\BenchmarkDotNet.Artifacts\resultsに移動する。 BenchmarkDotNet.Artifacts\results\BenchMark.WebApiClient-report.htmlを開く。 下図のようにサマリーと同様の内容が表示される。 logファイルとResultフォルダを控えておけば、報告資料や調査結果にそのまま利用できそう。 参考 No リンク 説明 1 【.NET/C#】メソッドのパフォーマンスを簡単に集計するライブラリの紹介 過去に書いたQuiitaの記事。内容はBenchmarkDotNetの紹介と使い方に関して記載した。 2 BenchmarkDotNetの公式ドキュメント 公式ドキュメントのリンク。 3 Github:本記事のソース 本記事のソースをGithubに公開してます。

Viewing all articles
Browse latest Browse all 9301

Trending Articles