15

ASP.NET MVC の小さなベンチマーク。ビューページ コード:

    public string Bechmark(Func<string> url)
    {
        var s = new Stopwatch();
        var n = 1000;

        s.Reset();
        s.Start();
        for (int i = 0; i < n; i++)
        {
            var u = url();
        }
        s.Stop();
        return s.ElapsedMilliseconds + " ms, " + ((s.ElapsedMilliseconds) / (float)n) + " ms per link<br/>";
    }

コードを表示:

<%= Bechmark(() => Url.Action("Login", "Account")) %>

<%= Bechmark(() => Url.Action("Login", "Account", new {username="bla", password="bla2", returnurl="blabla32", rememberme=false} )) %>

<%= Bechmark(() => Html.BuildUrlFromExpression<AccountController>(a=>a.ChangePassword("bla", "bla", "ya")) ) %>

ASP.NET MVC Beta を使用して、既定の新しいプロジェクト テンプレートの一般的な Core2 ノートブックでこれを実行すると、次の結果が得られます。

38 ミリ秒、リンクあたり 0,038 ミリ秒

120 ミリ秒、リンクあたり 0.12 ミリ秒

54 ミリ秒、リンクあたり 0.054 ミリ秒

全部で約 100 のメソッドと 30 のルーティング テーブル エントリを持つ約 10 のコントローラーを使用して実稼働プロジェクトで同じベンチマークを実行すると、式ベースのメソッドのパフォーマンスが大幅に低下します。

31 ミリ秒、リンクあたり 0.031 ミリ秒

112 ミリ秒、リンクあたり 0.112 ミリ秒

450 ミリ秒、リンクあたり 0.45 ミリ秒

私たちはこの方法をかなり頻繁に使用し (保守性)、いくつかのパフォーマンス ベンチマークを行っています。これにより、サイトのパフォーマンスが大幅に低下します。ページには、そのようなリンクがすぐに約 30 以上含まれます。つまり、1 つのページで 10 ミリ秒の追加のオーバーヘッドが発生します。URL ごとに 0.112 ミリ秒であっても、純粋な CPU オーバーヘッドは約 4 ミリ秒です。

MVC Preview 3 と Beta (昨日リリース) の間の 3 つの URL 生成呼び出しすべてのパフォーマンスが 5 倍改善されたことに注意してください。

スタック オーバーフローは同じフレームワークを使用していると思われますが、皆さんはこのスケーリングの問題にどのように取り組んでいますか? フロントページ (たくさんのリンク) と事前にレンダリングされたコントロールのリベラルなキャッシュ?

ASP.NET MVC の他の実稼働 Web サイトで、パフォーマンスの問題やヒントがあるものはありますか?

4

4 に答える 4

4

私はMSフォーラムでこの質問をしましたが、MSMVC開発者から回答を得ました。

ポスト

答え

MVCプレビュー2から昨日から最近リリースされたMVCベータまで、ルーティングに多くの変更がありました。これらの変更の一部には、パフォーマンスの向上が含まれます。アプリケーションでURL生成のパフォーマンスを向上させるための秘訣は次のとおりです。

  1. 名前付きルートを使用します。名前付きルートは、ルーティングのオプション機能です。名前はURL生成にのみ適用され、着信URLの照合に使用されることはありません。URLを生成するときに名前を指定すると、その1つのルートのみが一致しようとします。これは、指定した名前付きルートがルートテーブルの100番目のルートであっても、そのルートに直接ジャンプして一致を試みることを意味します。

  2. 最も一般的なルートをルートテーブルの先頭に配置します。これにより、URL生成と着信URLの処理の両方のパフォーマンスが向上します。ルーティングは、最初の一致が勝つというルールに基づいて機能します。最初の一致がルートテーブルの100番目のルートである場合、それは99の他のルートを試行する必要があり、それらのいずれも一致しなかったことを意味します。

  3. URL生成を使用しないでください。好きな人もいれば嫌いな人もいます。習得するのは少し難しいです。URLが非常に動的である場合に使用すると便利ですが、最初にURLが非常に少なく、URLがどのように表示されるかを正確に気にしない場合は、少し面倒になる可能性があります。

私のお気に入りのオプションは#1です。これは、非常に使いやすく、アプリ開発者の観点からURL生成をより決定的にするためです(それはあなたです!)。

于 2008-10-19T14:02:10.993 に答える
1

リンクをキャッシュすることは、プロセスの存続期間中は変更されないため (ほとんどのアプリでは)、おそらくチームにとって良い提案になるでしょう。

構成可能な形式 (web.config やデータベースなど) でルートの定義を開始するまでは、少し縮小する必要があります。

中央の例の遅延の大部分は、辞書に自動的に変換される匿名型にあると思われます。URL をキャッシュしても、ここでは役に立ちません。そのタイプを反映する必要があります。

それまでの間、必要な正確な入力を受け取る辞書ベースのリンクの一部に対して、独自のヘルパー メソッドを作成できます。その後、キャッシュを自分で処理できます。

于 2008-10-17T13:58:01.503 に答える
1

空のテンプレート プロジェクトに関する 2 つの追加メトリック:

<%= Bechmark(() => Url.Action("Login", "Account", new Dictionary<string, object> {{"username", "bla"}, {"password", "bla2"}, {"returnurl", "blabla32"}, {"rememberme", "false"}})) %>

<%= Bechmark(() => Url.Action("Login", "Account", new RouteValueDictionary(new Dictionary<string, object> {{"username", "bla"}, {"password", "bla2"}, {"returnurl", "blabla32"}, {"rememberme", "false"}}))) %>

結果:

71 ミリ秒、リンクあたり 0.071 ミリ秒

35 ミリ秒、リンクあたり 0.035 ミリ秒

かなり厄介なコードでパフォーマンスが大幅に向上します。残念な。

于 2008-10-17T14:15:11.467 に答える
0

リンクをキャッシュすることは、プロセスの存続期間中は変更されないため (ほとんどのアプリでは)、おそらくチームにとって良い提案になるでしょう。

リンクをキャッシュするにはどうすればよいですか。私が知る限り、それはできません。ルートが解決された後に実行されるメソッドをキャッシュする必要があるためです。これは遅い部分です。

于 2008-10-17T17:43:58.630 に答える