15 Stimmen

ASP.NET MVC URL-Generierungsleistung

Ein kleiner Benchmark mit ASP.NET MVC. Viewpage Code:

    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/>";
    }

Code anzeigen:

<%= 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")) ) %>

Die Ausführung dieses Vorgangs auf einem typischen Core2-Notebook mit der Standardvorlage für neue Projekte mit ASP.NET MVC Beta führt zu folgenden Ergebnissen:

38 ms, 0,038 ms pro Verbindung

120 ms, 0,12 ms pro Verbindung

54 ms, 0,054 ms pro Verbindung

Bei der Durchführung desselben Benchmarks auf einem Produktionsprojekt mit etwa 10 Controllern, die insgesamt etwa 100 Methoden und 30 Routing-Tabelleneinträge haben, verschlechtert sich die Leistung bei der ausdrucksbasierten Methode erheblich:

31 ms, 0,031 ms pro Verbindung

112 ms, 0,112 ms pro Verbindung

450 ms, 0,45 ms pro Verbindung

Wir verwenden diese Methode recht häufig (Wartungsfreundlichkeit), und bei Leistungsvergleichen zeigt sich, dass dies die Leistung der Website stark beeinträchtigt - Seiten enthalten schnell 30 oder mehr solcher Links, was 10 ms zusätzlichen Overhead auf einer einzigen Seite bedeutet. Selbst 0,112ms pro URL sind etwa 4ms reiner CPU-Overhead.

Es ist anzumerken, dass die Leistung aller drei URL-Generierungsaufrufe zwischen MVC Preview 3 und Beta (gestern veröffentlicht) um den Faktor 5 verbessert wurde.

Stack Overflow wird angeblich von demselben Framework betrieben, wie habt ihr dieses Skalierungsproblem gelöst? Liberale Zwischenspeicherung der Titelseite (viele Links) und vorgerenderte Steuerelemente?

Gibt es andere Produktionswebsites in ASP.NET MVC mit Leistungsproblemen oder gute Tipps?

4voto

CVertex Punkte 17701

Ich habe diese Frage in den MS-Foren gestellt und eine Antwort von einem MS MVC-Entwickler erhalten.

Der Posten

Die Antwort

Von MVC Preview 2 bis zur kürzlich veröffentlichten MVC Beta von gestern gab es eine Menge Änderungen am Routing. Einige dieser Änderungen beinhalten Leistungsverbesserungen. Hier sind einige Tricks, um die URL-Generierung in Ihrer Anwendung leistungsfähiger zu machen:

  1. Benannte Routen verwenden. Benannte Routen sind eine optionale Funktion des Routings. Die Namen gelten nur für die URL-Generierung - sie werden niemals für den Abgleich eingehender URLs verwendet. Wenn Sie bei der Generierung einer URL einen Namen angeben, wird nur versucht, diese eine Route zu finden. Das heißt, selbst wenn die von Ihnen angegebene benannte Route die 100. in der Routentabelle ist, werden wir sie direkt anspringen und versuchen, sie zu finden.

  2. Legen Sie die am häufigsten genutzten Routen an den Anfang der Routentabelle. Dadurch wird die Leistung sowohl bei der URL-Generierung als auch bei der Verarbeitung eingehender URLs verbessert. Das Routing funktioniert nach der Regel, dass die erste Übereinstimmung gewinnt. Wenn die erste Übereinstimmung die 100. Route in Ihrer Routentabelle ist, bedeutet dies, dass 99 andere Routen ausprobiert werden mussten und keine von ihnen übereinstimmte.

  3. Verwenden Sie keine URL-Generierung. Manche Leute mögen es, manche nicht. Es ist ein bisschen schwierig zu meistern. Es ist gut, wenn Ihre URLs sehr dynamisch sind, aber es kann ein bisschen lästig sein, wenn Sie nur wenige URLs haben und es Ihnen vielleicht egal ist, wie sie genau aussehen.

Meine bevorzugte Option ist Nr. 1, da sie sehr einfach zu verwenden ist und die URL-Generierung aus Sicht des App-Entwicklers (das sind Sie!) deterministischer ist.

1voto

Ben Scheirman Punkte 39742

Das Caching von Links wäre wahrscheinlich ein guter Vorschlag für das Team, da sie sich während der gesamten Dauer des Prozesses nicht ändern werden (bei den meisten Anwendungen sowieso).

Solange Sie Ihre Routen nicht in konfigurierbarer Form definieren (z. B. in der web.config oder in einer Datenbank), müssen Sie ein wenig zurückstecken.

Ich vermute, dass ein großer Teil der Verzögerung im mittleren Beispiel auf den anonymen Typ zurückzuführen ist, der automatisch in ein Wörterbuch umgewandelt wird. Zwischenspeichern der URL würde nicht helfen, hier b/c Sie müssten noch diesen Typ zu reflektieren.

In der Zwischenzeit können Sie Ihre eigenen Hilfsmethoden für einige dieser wörterbuchbasierten Verknüpfungen erstellen, die genau die von Ihnen benötigten Eingaben erfordern. Dann können Sie das Caching selbst übernehmen.

1voto

rudib Punkte 261

Ok, zwei zusätzliche Metriken für das leere Vorlagenprojekt:

<%= 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"}}))) %>

Ergebnisse:

71 ms, 0,071 ms pro Verbindung

35 ms, 0,035 ms pro Verbindung

Viel bessere Leistung mit viel schlechterem Code. Schade.

0voto

bashmohandes Punkte 2326

Das Zwischenspeichern von Links wäre wahrscheinlich eine gute Vorschlag für das Team, da sie sich während der gesamten Dauer des Prozesses nicht ändern (bei den meisten Anwendungen sowieso).

Wie kann man Links zwischenspeichern? Soweit ich weiß, ist das nicht möglich, weil man die Methode zwischenspeichern muss, die ausgeführt wird, nachdem die Route aufgelöst wurde, was der langsame Teil ist.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X