Summary
ASP.NET Coreアプリの軽量化って、つい『キャッシュ活用』とか『非同期処理』みたいな定番ネタに走りがちですが、実は設計段階での選択が思わぬボトルネックになってることも。最近あるプロジェクトで、たった1つの顧客データ取得APIに百数十ミリ秒もかかっている事象を解析したら、クリーンアーキテクチャの『副作用』みたいな部分が見えてきて… Key Points:
- クリーンアーキテクチャの設計思想とパフォーマンスの微妙な関係——階層化がもたらすマッピング処理のオーバーヘッド(実際に70ms近く消費するケースも)をどう緩和するか
- DIコンテナやバリデーション処理といった「裏方」が占める時間比率(全体の50%以上!)を削減する実践的なチューニング手法
- APIレスポンスが100msを超える場合の盲点——DBアクセス以外で発生する隠れたコストの特定方法と、最小限の改修で20〜30%改善した具体例
読者の方にちょっとした注意を。この記事では、さまざまなプロジェクトで見かけたパターンをもとに、アーキテクチャ設計と最適化についていくつかの手法や考え方を紹介している。で、その中に出てくる数字っぽい話はあくまで雰囲気と思ってほしい。現実には環境によって結果が全然違うこともあるから、自分のアプリでちゃんと検証したほうがいいかもしれない。
さて、高速なASP.NET Coreアプリケーションを目指す時、多くの人が細かい部分ばかり気にしがちだ。LINQよりforeach使ったらどうとか、文字列連結を工夫するとちょっとだけ速かったりとか、メモリの扱いを変えてみたり。でも、こういう小さい調整だけで性能が劇的に変わったという話はあまり耳にしない。
むしろ開発初期の構造設計――たとえばクリーンアーキテクチャの採用方法やサービスごとのライフサイクル管理みたいな、大枠で決めること――これらが後々になって響いてくることもあるようだ。どこまで影響するかはケースバイケースだけど、ほんの数割くらい差が生じた例もちらほら聞く。
まあ正直言って構造次第で伸び代は大きかったり小さかったり曖昧なんだけど、それでも「何となく」設計してしまうよりは意識して選んだほうが良い方向に向かいやすい、と感じている人も多そうだ。
要するに細かなコード書き換えよりも、土台になる建て付けこそ優先した方が長期的には役立つ場面も少なくない――そんなところかな。
さて、高速なASP.NET Coreアプリケーションを目指す時、多くの人が細かい部分ばかり気にしがちだ。LINQよりforeach使ったらどうとか、文字列連結を工夫するとちょっとだけ速かったりとか、メモリの扱いを変えてみたり。でも、こういう小さい調整だけで性能が劇的に変わったという話はあまり耳にしない。
むしろ開発初期の構造設計――たとえばクリーンアーキテクチャの採用方法やサービスごとのライフサイクル管理みたいな、大枠で決めること――これらが後々になって響いてくることもあるようだ。どこまで影響するかはケースバイケースだけど、ほんの数割くらい差が生じた例もちらほら聞く。
まあ正直言って構造次第で伸び代は大きかったり小さかったり曖昧なんだけど、それでも「何となく」設計してしまうよりは意識して選んだほうが良い方向に向かいやすい、と感じている人も多そうだ。
要するに細かなコード書き換えよりも、土台になる建て付けこそ優先した方が長期的には役立つ場面も少なくない――そんなところかな。
.NET Coreアプリケーションのパフォーマンスについて、単なる構文の話を超えて、少し奥深い部分――つまり設計そのものに視点を移してみたくなる時がある。クリーンアーキテクチャというもの、聞いたことがある人も多いはず。あれって、保守性とかテストのしやすさに重きを置いてるけど、その分構造が複雑になりやすい印象もある。ただ、それがパフォーマンス面でどう影響するか…実際には結構曖昧なところ。
例えばASP.NET CoreでよくあるAPIの設計――ざっくり言えば、
コントローラー → サービス → リポジトリ → データベース
みたいな階層になるケースが目立つ。各層ごとにモデル(データ構造)が違ったりして、そのたびマッピング処理が発生する仕組みらしい。このへん、ちょっとしたAPIでもレスポンス遅延につながることが観察されているっぽい。
実際、「顧客データを取ってきて返すだけ」みたいなシンプルなエンドポイントですら、一部では百ミリ秒ちょっとくらいかかる例もちらほら見かける。そのうちDBクエリ自体はほんの数十ミリ秒前後で終わっていることも多くて、「え?じゃあ残りは?」と疑問に思う場面も出てきたり。
プロファイリングしてみると、大まかにはこんな感じ:
・オブジェクト間マッピングで何十ミリ秒(七十ミリ秒弱?)
・依存解決処理(DIコンテナ)が約三割くらい消費
・バリデーションやビジネスロジック部分で四分の一程度時間を取られてしまう
このあたり、全部合わせると意外と馬鹿にならない。それでも「もうクリーンアーキテクチャやめよう!」とはならず、むしろ工夫次第で改善余地はいくらでも見つかる印象。捨てなくても大丈夫そう。
対策としては…例えばレイヤーごとの責務整理だったり無駄なマッピング減らしたり、本当に必要な依存だけ注入するなど。大幅な変更じゃなくても、小さめの調整から始めればそれなりに応答速度アップできそうだ――そんな声もちらほら聞こえてくる。
Extended Perspectives Comparison:
テーマ | 内容 |
---|---|
Minimal APIのパフォーマンス向上 | 処理能力が20~30%向上し、初回レスポンス時間が半減することもある。 |
適用状況 | 小規模なマイクロサービス、大量アクセスを捌くAPI、簡単なCRUD操作に有効。 |
ハイブリッド型アプローチ | 重要情報はSignalRで通知し、それ以外はHTTPで読み込む方法がバランス良いとされる。 |
システムモニタリングの重要性 | クライアントとサーバー両方を監視しないと正しい構成が分からないことが多い。 |
設計の最適化 | アプリケーションの初期設計やデータフローに注意を払い、高速化につながる可能性が高い。 |

選択的にモデルを隣接レイヤー間で使い回すことで、どうもマッピングの負担がぐっと減ることがあるみたいだ。依存関係を深く重ねず平坦にしたり、読み書きを分けてリード側が無駄な層をすっ飛ばせるようなCQRSの仕組みも、それなりに効果が出やすい手法として語られている。ただ、どれくらい速くなるかはアプリケーションの構造や元々の設計によって幅がありそう。よく例に挙げられるケースではレスポンス時間が三割くらいまで短縮されたとか聞いた覚えがある。たとえば百数十ミリ秒掛かっていた処理が、半分よりもうちょっと下くらいになる感じ。
以前だとサービスメソッドは依存先も多くて、あれこれマッピングしながら進める流れだったんだけど――
// こんな感じで何段階も経由してた
public async Task<CustomerResponseDto> GetCustomerAsync(int id)
{
var customerEntity = await _customerRepository.GetByIdAsync(id);
var customerModel = _mapper.Map<CustomerModel>(customerEntity);
await _validationService.ValidateCustomerAsync(customerModel);
return _mapper.Map<CustomerResponseDto>(customerModel);
}
最近はクエリーの読み取り専用ハンドラで直接DBからDTOへ射影するパターンも見かける。
// CQRS的なクエリハンドラ
public async Task<CustomerResponseDto> Handle(GetCustomerQuery query)
{
// 途中を省いて直接返却
return await _dbContext.Customers
.Where(c => c.Id == query.CustomerId)
.Select(c => new CustomerResponseDto {
Id = c.Id,
Name = c.Name,
// 他にもプロパティ色々
})
.FirstOrDefaultAsync();
}
---
サービスのライフタイム設定(シングルトン・スコープド・トランジェント)が地味に全体性能へ響く場面って意外と多い気もする。ASP.NET Coreだと、この辺りちゃんと考えないまま実装すると、後から記憶以上にメモリ消費やスループット落ちてたりするケースがちらほら。
ちなみにサービス解決時のオーバーヘッドについてテストするとき、一万件ほど連続でリクエスト投げて同時接続百本くらい走らせたり…そんなベンチマーク例もあるにはある。
// テスト: 1万リクエスト & 100並列コネクション、それぞれ15個ぐらい異なるライフタイムサービス解決して利用
結果を見ると結構大きめの違いになって表れることもある。ただ、その「劇的」と言えるほどなのかどうかは状況次第かなと思う。
サービスのライフタイムを見直してみると、たしかに一部のサービスをシングルトンとして扱うことで、体感としては七割近くスループットが上がったという話も耳にしたことがある。だけど、これって環境やアプリの構造によってけっこう違いそうで、一概には言えないかもしれない。実際、自前のアプリケーションでBenchmarkDotNetみたいなツールを使って計測してみたほうが確実だと思う。
どういうサービスをどんなライフタイムで登録するか、その辺りになると人によって意見は分かれるけど、大まかな指針はいくつか知られている。例えば、多くの場合データベースとのやり取りなんかはスコープドが普通だし、依存関係にスコープドなものがなければ無理せずシングルトンでもいいんじゃないかな、といわれたりもする。トランジェントについては、毎回状態を変えたいような場合だけ必要になるとか聞いたことある。
コード例だと、キャッシュサービスや設定値まわり、それからマッパーとかロガーみたいなのはシングルトンで登録されていたりする。一方でDBコンテキストやユーザー関連のサービスなんかはスコープドになっていて、ファイル処理とか通知ビルダーみたいな一回限りの仕事にはトランジェント…そんなイメージだったと思う。
さてミドルウェアの順番だけど、この順序次第でレスポンス速度に差が出ることもあるらしい。たとえばSaaS系のシステムだと、一日のリクエスト数が膨大になるケースもあって、その中には静的ファイルやヘルスチェック用の通信など、認証なんて全然不要なアクセスも混じっているとか。それなのに認証ミドルウェアを早めに配置しちゃうと、本来通さなくてもいいリクエストまで全部認証処理されてしまい無駄という声も出る。
昔よく見た構成ではHTTPSリダイレクト→認証→認可→静的ファイル→ルーティング…みたいな流れだったんだけど、それだと静的コンテンツにも全部認証フィルターが掛かっちゃう。でも最近では、「静的ファイル配信はもっと前段階」「ヘルスチェックなんてローカルからなら素通し」みたいな書き方に変える事例も増えてきた。
つまりHTTPSリダイレクトした後すぐ静的ファイルへ行くようにして、そのあとで本格的なルーティングや必要ならヘルスチェックへの特別対応を書いておき、そのあとようやく認証・認可処理…こんな順番になっていたりする。これによって一部ケースでは無駄な計算資源消費を抑えられる可能性がありそう。ただし全体への影響度合いは運用条件によるので、一概には言えない部分も残るようだ。
どういうサービスをどんなライフタイムで登録するか、その辺りになると人によって意見は分かれるけど、大まかな指針はいくつか知られている。例えば、多くの場合データベースとのやり取りなんかはスコープドが普通だし、依存関係にスコープドなものがなければ無理せずシングルトンでもいいんじゃないかな、といわれたりもする。トランジェントについては、毎回状態を変えたいような場合だけ必要になるとか聞いたことある。
コード例だと、キャッシュサービスや設定値まわり、それからマッパーとかロガーみたいなのはシングルトンで登録されていたりする。一方でDBコンテキストやユーザー関連のサービスなんかはスコープドになっていて、ファイル処理とか通知ビルダーみたいな一回限りの仕事にはトランジェント…そんなイメージだったと思う。
さてミドルウェアの順番だけど、この順序次第でレスポンス速度に差が出ることもあるらしい。たとえばSaaS系のシステムだと、一日のリクエスト数が膨大になるケースもあって、その中には静的ファイルやヘルスチェック用の通信など、認証なんて全然不要なアクセスも混じっているとか。それなのに認証ミドルウェアを早めに配置しちゃうと、本来通さなくてもいいリクエストまで全部認証処理されてしまい無駄という声も出る。
昔よく見た構成ではHTTPSリダイレクト→認証→認可→静的ファイル→ルーティング…みたいな流れだったんだけど、それだと静的コンテンツにも全部認証フィルターが掛かっちゃう。でも最近では、「静的ファイル配信はもっと前段階」「ヘルスチェックなんてローカルからなら素通し」みたいな書き方に変える事例も増えてきた。
つまりHTTPSリダイレクトした後すぐ静的ファイルへ行くようにして、そのあとで本格的なルーティングや必要ならヘルスチェックへの特別対応を書いておき、そのあとようやく認証・認可処理…こんな順番になっていたりする。これによって一部ケースでは無駄な計算資源消費を抑えられる可能性がありそう。ただし全体への影響度合いは運用条件によるので、一概には言えない部分も残るようだ。

なんかね、ミドルウェアの順番をちょっといじるだけで、アクセスがやたら多いアプリの場合はコスト面とか速度で意外と差が出るって話をどこかで聞いたことがある。実際のところは、自分の環境でApplication Insightsみたいな監視ツールを使って様子を見るほうが確かっぽい。まあ、全部一概には言えないけど。
.NET 6からだったかな?最小API(Minimal API)っていう書き方が目立つようになったんだよね。たいてい「記述量が減る」程度に思われてるけど、パフォーマンス面でも少し注目しても良さそう。細かい数字までは覚えてないけど、人によっては体感できるくらい違うらしい。
例えば似たような機能――天気予報を返すAPI――なんだけど、昔ながらのコントローラー方式と最小API方式、それぞれこんな感じ。
// 伝統的なコントローラー
[ApiController]
[Route("[controller]")]
public class WeatherController : ControllerBase
{
[HttpGet]
public IEnumerable
.NET 6からだったかな?最小API(Minimal API)っていう書き方が目立つようになったんだよね。たいてい「記述量が減る」程度に思われてるけど、パフォーマンス面でも少し注目しても良さそう。細かい数字までは覚えてないけど、人によっては体感できるくらい違うらしい。
例えば似たような機能――天気予報を返すAPI――なんだけど、昔ながらのコントローラー方式と最小API方式、それぞれこんな感じ。
// 伝統的なコントローラー
[ApiController]
[Route("[controller]")]
public class WeatherController : ControllerBase
{
[HttpGet]
public IEnumerable
Get()
{
return GenerateForecasts();
}
}
// 最小API
app.MapGet("/weather", () => GenerateForecasts());
これだけ見ると、「ただ短く書けるだけじゃ?」って思うかもしれない。でも現場によっては負荷対策とか運用コストとか、その辺りにも関係してくることもあるみたい。もちろん絶対こうなるとは限らないし、ちゃんと計測して判断するのが無難かも。まあ全部鵜呑みにせず、その都度確かめてみるくらいでいいんじゃないかな、と時々考える。
マイクロソフトの公式資料や、一部コミュニティで言われている話なんだけど、Minimal APIの実装だと従来よりパフォーマンスがそこそこ良くなることが多いみたい。具体的な数字はちょっと曖昧だけど、処理できるリクエスト数が二~三割ほど増えたとか、最初のレスポンスが返ってくるまでの時間も半分くらい早くなったという報告もあったような気がする。まあ、これは単にコードが短くなるとかそういう話じゃなくて、裏側でコントローラーを探したりアクションを決めたりフィルターを通したり…みたいな余計な手間を省けるかららしい。
ただ全部の場面で向いているわけでもなくて、小さい機能に絞ったマイクロサービスとか、とにかく大量アクセスさばかなきゃいけないAPI、高度なビジネスロジックじゃなくて簡単なCRUD操作だけやる場合なんかでは結構役立つこともあるっぽい。でも例えば認証とかバリデーションとか、色んな共通処理が複雑になってくると、やっぱり従来のコントローラー構造の方が運用しやすいかなって声もちらほら見かける。
まあ要するにケースバイケース。全部Minimal APIでいいってわけでもないし、その逆でもない感じ。最近はこの辺選択肢も増えてきたから、自分たちの用途によって使い分ける人も増えてきてる印象。
ただ全部の場面で向いているわけでもなくて、小さい機能に絞ったマイクロサービスとか、とにかく大量アクセスさばかなきゃいけないAPI、高度なビジネスロジックじゃなくて簡単なCRUD操作だけやる場合なんかでは結構役立つこともあるっぽい。でも例えば認証とかバリデーションとか、色んな共通処理が複雑になってくると、やっぱり従来のコントローラー構造の方が運用しやすいかなって声もちらほら見かける。
まあ要するにケースバイケース。全部Minimal APIでいいってわけでもないし、その逆でもない感じ。最近はこの辺選択肢も増えてきたから、自分たちの用途によって使い分ける人も増えてきてる印象。

HTTPって、昔から使われてるけど、最近リアルタイムな更新が必要なアプリ増えてきたから、SignalRの構成をどうするかって悩む人が多いみたい。例えばダッシュボード系の画面だと、やり方によって反応速度やサーバーの負荷が結構変わるらしい。
ざっくり三つくらいパターンがあるっぽい。一つ目は普通にREST APIでデータ取って、それとは別にSignalRだけで通知飛ばす方法。二つ目はもう全部SignalRだけで通信してしまう形。三番目は折衷案的なもので、大事な情報更新はSignalRで、それ以外はHTTPから読み込む流れ。
千人規模くらいの同時アクセスを想定した話なんだけど、現場の声とか観察結果ではね…完全に一つに絞り切れる訳じゃなくて、ハイブリッド型(つまりクリティカルな部分のみSignalR使うやり方)がバランス良さそうだね、という意見も出ている。ただ実際にはシステムごとに事情違うし、「これなら絶対大丈夫」とまでは言えないと思う。
あと気になったんだけど、やっぱりクライアント側もサーバー側も両方ちゃんとモニタリングしないと、本当にその構成が合ってるか分かんないことが多いみたい。最適解探すには、手間かけて様子を見るしかないかなぁ、と感じることもあるよね。
ざっくり三つくらいパターンがあるっぽい。一つ目は普通にREST APIでデータ取って、それとは別にSignalRだけで通知飛ばす方法。二つ目はもう全部SignalRだけで通信してしまう形。三番目は折衷案的なもので、大事な情報更新はSignalRで、それ以外はHTTPから読み込む流れ。
千人規模くらいの同時アクセスを想定した話なんだけど、現場の声とか観察結果ではね…完全に一つに絞り切れる訳じゃなくて、ハイブリッド型(つまりクリティカルな部分のみSignalR使うやり方)がバランス良さそうだね、という意見も出ている。ただ実際にはシステムごとに事情違うし、「これなら絶対大丈夫」とまでは言えないと思う。
あと気になったんだけど、やっぱりクライアント側もサーバー側も両方ちゃんとモニタリングしないと、本当にその構成が合ってるか分かんないことが多いみたい。最適解探すには、手間かけて様子を見るしかないかなぁ、と感じることもあるよね。
とある大手ECサイトの事例なんだけど、ちょっと昔ながらの多層構成を使ってたみたい。サービスは全部、まあ利用者ごとに新しく作られるやり方になってたんだとか。ページを一回表示するだけで複数回データベースにアクセスする必要があったみたいで、多いときは五回近く問い合わせていた気がする。
EF Coreでは関連情報も最初からまとめて取得していたっぽいけど、その辺が何となく負荷につながっていた可能性もありそう。
商品一覧ページが表示されるまでに、七百ミリ秒を軽く超えるくらい時間がかかったとの話も聞こえてきた。ユーザー数が千人規模まで増えると、メモリー消費量も四ギガバイト前後まで膨れてしまうような状況だったらしい。
ちなみにアプリケーションの起動時、かなり待つことになってしまい、一〇秒を超えてやっと立ち上がることも珍しくなかったという。
細かい部分は多少違ったかもしれないけど、おおまかにはこんな感じの状況だったと思われる。
EF Coreでは関連情報も最初からまとめて取得していたっぽいけど、その辺が何となく負荷につながっていた可能性もありそう。
商品一覧ページが表示されるまでに、七百ミリ秒を軽く超えるくらい時間がかかったとの話も聞こえてきた。ユーザー数が千人規模まで増えると、メモリー消費量も四ギガバイト前後まで膨れてしまうような状況だったらしい。
ちなみにアプリケーションの起動時、かなり待つことになってしまい、一〇秒を超えてやっと立ち上がることも珍しくなかったという。
細かい部分は多少違ったかもしれないけど、おおまかにはこんな感じの状況だったと思われる。

建築の変化って、たぶん一言じゃまとまらない。いや、そもそも大きな流れで見ると、サービスのライフサイクルとかその辺からちょっとずつ手が入ったみたいだよ。読み取り専用のサービスは、ほぼ全て長く使い回す形(なんとなくシングルトンっぽい)にされてる気がするし、商品一覧については専用の読込モデルを別に作った例もあった。
それだけじゃなくて、何かキャッシュ…レスポンスキャッシュってやつ?あれも適当に(というか戦略的に?)組み込まれている印象。出力キャッシュのミドルウェアが商品リスト周りには加えられていて、そのキャッシュも商品データが更新されるたびに消されたりしていたような。全部常に新しいわけじゃなくて、ときどき情報が古くても良い場合には、このやり方はまぁまぁ効く場面もあると思う。
データアクセスについては…昔ながらのエンティティごと持ってくる方式じゃなくて、一部で投影クエリを多めに使うようになったみたい。人気画面とかでは正規化より多少冗長な読み込み専用モデルを作って、それで素早く表示できるよう工夫した話もちょこちょこ聞いたかな。
API自体にも手直し入ってて、高アクセスなパスでは「ミニマルAPI」へ切り替えたこともあったらしい。全部そうなったわけでもないけど、人が多く見る部分だけでも簡素化して余分なミドルウェアを減らしているとのこと。一部公開エンドポイントでは特に効果ある場合があったとか。
例えばコードで言えば――前はコントローラー形式だったよね、多分。ただ、そのやり方だとデータ取得時に色々まとめてロードしちゃうから無駄も多かった気配。でも最近だと、「/products」パスでパラメーター渡せば必要最低限だけ取り出して即返す形になってたりする。関連する名前や平均評価くらいなら、一度の問い合わせで済むよう調整されている。
しかもレスポンスには数分程度(七八分くらい?)有効なキャッシュ制御まで混ぜ込んでいる場合が増えた印象。その間は同じリストを再利用できるので、人によっては待ち時間短縮になることもある、と聞いた覚えあり。ただし常に最新とは限らないため、ケースバイケースと言えるかもしれないね。
それだけじゃなくて、何かキャッシュ…レスポンスキャッシュってやつ?あれも適当に(というか戦略的に?)組み込まれている印象。出力キャッシュのミドルウェアが商品リスト周りには加えられていて、そのキャッシュも商品データが更新されるたびに消されたりしていたような。全部常に新しいわけじゃなくて、ときどき情報が古くても良い場合には、このやり方はまぁまぁ効く場面もあると思う。
データアクセスについては…昔ながらのエンティティごと持ってくる方式じゃなくて、一部で投影クエリを多めに使うようになったみたい。人気画面とかでは正規化より多少冗長な読み込み専用モデルを作って、それで素早く表示できるよう工夫した話もちょこちょこ聞いたかな。
API自体にも手直し入ってて、高アクセスなパスでは「ミニマルAPI」へ切り替えたこともあったらしい。全部そうなったわけでもないけど、人が多く見る部分だけでも簡素化して余分なミドルウェアを減らしているとのこと。一部公開エンドポイントでは特に効果ある場合があったとか。
例えばコードで言えば――前はコントローラー形式だったよね、多分。ただ、そのやり方だとデータ取得時に色々まとめてロードしちゃうから無駄も多かった気配。でも最近だと、「/products」パスでパラメーター渡せば必要最低限だけ取り出して即返す形になってたりする。関連する名前や平均評価くらいなら、一度の問い合わせで済むよう調整されている。
しかもレスポンスには数分程度(七八分くらい?)有効なキャッシュ制御まで混ぜ込んでいる場合が増えた印象。その間は同じリストを再利用できるので、人によっては待ち時間短縮になることもある、と聞いた覚えあり。ただし常に最新とは限らないため、ケースバイケースと言えるかもしれないね。
アプリケーションの最初の設計や、どれだけ複雑かっていう点、それからどこまで最適化に力を入れるかで、結果はけっこう違うみたい。なんとなく基準を作っておいて、それぞれ段階ごとにパフォーマンスがどう変化するか確かめてみるのが良さそうだよね。
さて、アーキテクチャについてだけど、細かいコードの書き方よりも骨組みのほうが効果が出やすい場面、実際にはけっこう多い気がするんだ。ASP.NET Coreとか使って高性能なウェブアプリを作るなら、まず全体像をざっと見直しておいたほうがいいんじゃないかなあと思う。たとえば、「アルゴリズムより構造」なんて言葉も聞いたことがあるし。
それと、大事なポイントはいくつかあるんだけど…順番もあまり決まってないけど思いついたところから話すね。サービスのライフタイム(シングルトンにするかどうかとか)は負荷が高まった時には意外と大きな差になることもあるらしい。それからデータの流れ方によって設計を工夫したりとか、プラットフォーム独自の機能(ミニマルAPIだったりエンドポイントルーティングだったりキャッシュ的なものだったり)もうまくハマれば助けになるみたい。
でもやっぱり「理論上速そう」だけじゃ判断できないところもあるし、何度もベンチマークで実測して確認していくしかない…という話になる。BenchmarkDotNetとかApplication Insightsとか、他にも負荷テスト用ツールはいろいろ見かけるね。
もちろん「これさえやれば完璧!」なんてことはまずなくて、結局土台となる設計次第で後々悩む量も変わる印象かな…。だから開発初期にちゃんと考えておけば保守もしやすくなるし、高速化もしやすい仕組みになる可能性は十分ありそうだよ。場合によっては、小さな最適化より構造そのものへの手当てが効いてくる―そんな感じだと思う。
さて、アーキテクチャについてだけど、細かいコードの書き方よりも骨組みのほうが効果が出やすい場面、実際にはけっこう多い気がするんだ。ASP.NET Coreとか使って高性能なウェブアプリを作るなら、まず全体像をざっと見直しておいたほうがいいんじゃないかなあと思う。たとえば、「アルゴリズムより構造」なんて言葉も聞いたことがあるし。
それと、大事なポイントはいくつかあるんだけど…順番もあまり決まってないけど思いついたところから話すね。サービスのライフタイム(シングルトンにするかどうかとか)は負荷が高まった時には意外と大きな差になることもあるらしい。それからデータの流れ方によって設計を工夫したりとか、プラットフォーム独自の機能(ミニマルAPIだったりエンドポイントルーティングだったりキャッシュ的なものだったり)もうまくハマれば助けになるみたい。
でもやっぱり「理論上速そう」だけじゃ判断できないところもあるし、何度もベンチマークで実測して確認していくしかない…という話になる。BenchmarkDotNetとかApplication Insightsとか、他にも負荷テスト用ツールはいろいろ見かけるね。
もちろん「これさえやれば完璧!」なんてことはまずなくて、結局土台となる設計次第で後々悩む量も変わる印象かな…。だから開発初期にちゃんと考えておけば保守もしやすくなるし、高速化もしやすい仕組みになる可能性は十分ありそうだよ。場合によっては、小さな最適化より構造そのものへの手当てが効いてくる―そんな感じだと思う。
Reference Articles
C# CODING GUIDELINES 2024 #プログラミング
開発 環境は Visual Studio 2022(以下VS2022) を想定しています。 最新の環境の方が補完機能なども優れているので、生産性やコード品質が上がります。
Source: QiitaOWASP ZAP で Web アプリケーション セキュリティ対策
6.2.1 ログインフォームを修正 · 6.2.2 csrf のゲッターとセッターを自動生成 · 6.2.3 CSRF トークンを設定 · 6.2.4 リクエストにある CSRF トークンを照合する処理を追加 ...
Source: 株式会社SEプラス
Related Discussions