問題タブ [benchmarkdotnet]

For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.

0 投票する
1 に答える
1622 参照

c# - Newtonsoft.Json デシリアライゼーションのベンチマーク: ストリームおよび文字列から

Newtonsoft.Jsonを使用して HTTP 応答 JSON ペイロードを逆シリアル化する 2 つのアプローチのパフォーマンス (速度、メモリ使用量) の比較に興味があります。

ストリームを使用するためのNewtonsoft.Json の Performance Tipsは知っていますが、もっと知りたいと思っていました。BenchmarkDotNetを使用して簡単なベンチマークを作成しましたが、結果に少し困惑しています (以下の数値を参照)。

私が得たもの:

  • ストリームからの解析は常に高速ですが、それほど多くはありません
  • 文字列を入力として使用すると、小規模および「中規模」の JSON を解析すると、より良いまたは同等のメモリ使用量になります。
  • メモリ使用量の大きな違いは、大規模な JSON で見られ始めます (文字列自体が LOH になる)。

(まだ) 適切なプロファイリングを行う時間がありませんでした。(エラーがない場合) ストリーム アプローチのメモリ オーバーヘッドに少し驚いています。コード全体はこちらです。

?

  • 私のアプローチは正しいですか?(使用法MemoryStream; シミュレートHttpResponseMessageとその内容; ...)
  • ベンチマーク コードに問題はありますか?
  • なぜこのような結果が表示されるのですか?

ベンチマークの設定

MemoryStreamベンチマークの実行中に何度も使用する準備をしています:

ストリームの逆シリアル化

文字列の逆シリアル化

最初に JSON をストリームから文字列に読み取り、次に逆シリアル化を実行します。別の文字列が割り当てられた後、逆シリアル化に使用されます。

一般的な方法

結果

小さな JSON

10000回繰り返し

  • ストリーム: 平均 25.69 ミリ秒、61.34 MB 割り当て
  • 文字列: 平均 31.22 ミリ秒、割り当てられた 36.01 MB

ミディアム JSON

1000回繰り返し

  • ストリーム: 平均 24.07 ミリ秒、12 MB 割り当て
  • 文字列: 平均 25.09 ミリ秒、割り当てられた 12.85 MB

大きな JSON

100回繰り返した

  • ストリーム: 平均 229.6 ミリ秒、47.54 MB 割り当て、オブジェクトは Gen 1 に到達
  • 文字列: 平均 240.8 ミリ秒、割り当てられた 92.42 MB、オブジェクトが Gen 2 に到達しました!

アップデート

のソースを調べたところ、 JsonConvert:816から逆シリアル化するときにwith をJsonConvert内部的に使用していることがわかりました。ストリームもそこに関与しています (もちろん!)。JsonTextReaderStringReaderstring

次に、それ自体をさらに掘り下げることにしましたStreamReaderが、一目惚れしました-常に配列 buffer ( byte[]): StreamReader:244を割り当てています。これは、そのメモリ使用を説明しています。

これで「なぜ」の答えが得られます。解決策は簡単です。インスタンス化するときに小さいバッファ サイズを使用します。StreamReader最小バッファ サイズのデフォルトは 128 ですが (「参考文献」を参照StreamReader.MinBufferSize)、任意の値を指定できます> 0(ctor オーバーロードの 1 つを確認してください)。

もちろん、バッファサイズデータの処理に影響します。次に使用する必要があるバッファ サイズに答えると、依存します。より小さな JSON 応答が予想される場合は、小さなバッファーに固執するのが安全だと思います。

0 投票する
0 に答える
787 参照

azure-devops - Azure Pipeline 内で BenchmarkDotNet ベンチマークを実行する

Azure DevOps パイプライン内で BenchmarkDotNet で作成されたベンチマークを実行しようとしています。これは私が問題を抱えているビルドです。ベンチマークの実行ステップを見てください。ご覧のとおり、ベンチマークを使用したすべてのテストに合格しましたが、実際には実行されたベンチマークはありません。ログからのメッセージ:

ベンチマークを使用してクラスに属性を追加InProcessすると、ベンチマークが実行されます。しかし、私のベンチマークの一部は長時間実行されているため、プロセス外のベンチマークを使用することを推奨する BenchmarkDotNet によって中断されます。

Azure パイプライン内でアウト プロセス ベンチマークを実行するにはどうすればよいですか?