Blazor WebAssembly HostedのアプリにMessagePackを使ってみる .NETラボ 勉強会 2023年1月
Blazor WebAssemblyHostedのアプリにMessagePackを使ってみる株式会社SAKURUGエンジニアリングユニット草場 友光.NETラボ 2023年1月
View Slide
自己紹介• 普段は主にWebFormsアプリの保守のお仕事をしてます。• 古めのシステムが多いので時代に取り残されぬよう新しい技術を一つでも入れるよう日々努力しています。• 2022/08-2023 Microsoft MVP(Developer Technologies)• tomo_kusaba
宣伝【VISION】ひとの可能性を開花させる企業であり続けるVISIONに共感できる仲間募集中。
注意• 個人の見解・解釈が多分に入っています。• 見解の相違・事実誤認などありましたらご指摘ください。• #dotnetlabでtweetすると右側に表示されます
今日の目的• 通常、WebAPIのシリアライザとしてはJSONシリアライザが使用されている。Webアプリケーションにおいてはパフォーマンスにおけるウェイトはデータベースやネットワークに比べシリアライザーは少ないと考えられる。• しかしながら、パフォーマンスチューニングは一般的に難しい• そこで、手軽なパフォーマンスアップの方法としてJSONシリアライザーをバイナリシリアライザであるMessagePack forC#に置き換えることでどれだけパフォーマンスアップできるか検証してみた
MessagePack for C#とは• C#用の超高速バイナリシリアライザ• .NET Standard2.0以上がターゲットで.NET Core 2.1以上向けの最適化がされている• 河合さん(@neuecc)/Microsoft MVP for DeveloperTechologiesにより開発• Visual Studio 2022の内部通信• SignalRのMessagePack Hub• Blazor Serverプロトコル
MessagePack for C#とは
MemoryPackとは• 河合さんによる最新の超高速バイナリシリアライザ• .NET 7及びC#11に最適化
何で速いのか??• この辺を読んでください• →https://neue.cc/2022/12/08_MemoryPackSessionInDotNetConfRecapTokyo.html
通常のBlazor WebAssembly+WebAPIサーバークライアント(ブラウザ)GETJSON(テキスト)
メリット・デメリット• メリット• OpenAPIのエコシステムを享受できる(Swaggerなど)• データのやりとりがテキストなので人間にも読める• デメリット• テキストへのシリアライズのコストが高い
検証• まずは、「WeatherForcast」のデモをMessagePackでシリアライズ/デシリアライズして正常に画面表示できるかどうかを検証する• MessagePackでのパフォーマンスを最大限に引き出すことが目的ではなく、いかに簡単にJSONシリアライザからMessagePackに置き換えるかを主眼に置いていることに留意していただきたい。
検証ーController• Controllerは以下のように変更• 戻り値の型を「IActionResult」• JSONシリアラズされないようFileとして返す
検証ーShared• MessagePackObject属性をつける
検証ーClient• MessagePackでデシリアライズ
結果• Weather forcastの表示ができました
サンプルの動作検証• Edgeの開発者ツールで内容確認したところバイナリデータで通信していると確認できます。
通常のWebアプリでは・・・• データベースとネットワークの時間が無視できない。• データベースとネットワークの時間の揺らぎが大きくそのままではシリアライズ・デシリアライズの差が出てくることが難しいのではと予想• .NETはJITであるため初回と2回目以降の速度に大きく差が出ると想定
今回の計測環境• データベースの読み取りの揺らぎ対策• サーバ内に結果をキャッシュし2回目以降は実データベースへ読みに行かないようにする。• 計測専用アプリであるので常に同じ結果を返す• ネットワークの揺らぎ対策• Webアプリケーションサーバで実行する• JITによる揺らぎ対策• 2回連続実行し2回目の値を採用する
サーバー側_dataはSingletonでDI2回目以降はデータありなのでDBアクセスなしに実行される
クライアント側計測の2回目を有効な値とする(アドバイス thanks:とっちゃん)以降、MessagePack、MemoryPackの計測に続く
クライアント側つづき
計測結果• 各、20ループJSON MessagePack MemoryPack計測1 637ms 293ms 218ms計測2 535ms 484ms 252ms計測3 853ms 345ms 231ms計測4 522ms 332ms 288ms計測5 625ms 537ms 305ms計測6 653ms 426ms 249ms計測7 713ms 341ms 222ms計測8 582ms 292ms 257ms計測9 484ms 289ms 211ms計測10 868ms 530ms 283ms平均 647ms 387ms 252ms
今回の場合の結果JSON MessagePack MemoryPack平均 647ms 387ms 252ms差 -260ms -135msサーバー側をWebAPIとしてシリアライザーをJSONからMessagePackまたはMemoryPackに置き換えただけの雑な実装でもそれなりにシリアライズ・デシリアライズ部分のパフォーマンス向上は見られることは分かった。しかし、実アプリケーションベースではどうだろうか??
実画面ベースでの実装• 先ほどのWebAPIを流用し画面のみを制作• 体感上、有意な変化があるのかそれぞれが判断して欲しいhttps://kind-moss-0af0a4d00.2.azurestaticapps.net/
実画面ベースでの比較(REST API)783ms
実画面ベースでの比較(Memory Pack)539ms
参考文献• MessagePack for C#(Github)• MemoryPack(Github)• System.Text.Json名前空間
おしまいおしまい