Wie bekomme ich meine Anwendung schneller? Diese Frage stellen mir viele meiner Kunden, die mich zu einer Performanceanalyse Ihrer .NET Anwendung einladen. Natürlich lässt sich eine solche Frage nicht pauschal beantworten. In der Regel hilft nur ein gezieltes Profiling der Anwendung. Trotzdem gibt es einige Best Practices, deren Einhaltung bereits enorm zur Steigerung der Anwendungsperformance führen können.
52 solcher Performance Tipps hat das Team von Red-Gate gesammelt. Dazu wurden Performance Experten aus der ganzen Welt gebeten ihre besten Tipps beizusteuern. Das Ergebnis ist ein kleines E-Book, zu dem ich auch zwei Tipps beitragen durfte.
Das Buch ist in die folgenden Bereiche gegliedert:
- Allgemeine Performance Ratschläge
- .NET Performance Verbesserungen
- ASP.NET Performance Tipps
- Tipps zum Datenzugriff
- Speicheroptimierung
- Generelle Tipps
Meine Tipps beziehen sich auf den Datenzugriff mit dem Entity Framework. Ein Problem, welches ich häufig beobachte besteht darin, dass Daten unnötig mit aktiviertem Change Tracking geladen werden. Change Tracking ist ein Mechanismus, der dafür sorgt, dass das Entity Framework über eine Veränderung der Daten einer Entität informiert wird. Über diesen Weg reicht später ein einfacher Aufruf der Methode SaveChanges am DBContext, um alle Änderungen automatisch zu sichern.
Häufig ist jedoch bereits beim Laden klar, dass die Daten nicht verändert werden. Nutzt man nun jedoch den Standardweg des Entity Framwork 6, wie ihn folgender Code zeigt, werden die Daten automatisch mit aktiviertem Change Tracking abgerufen.
using (var db = new NorthwindDb())
{
var shippers = db.Shippers.ToList();
foreach (var shipper in shippers)
{
Console.WriteLine("{0} - {1}", shipper.ShipperID, shipper.CompanyName);
}
}
Die Lösung des Problems ist relativ einfach. Ein Aufruf der Erweiterungsmethode AsNoTracking() deaktiviert das Change-Tracking für die über diesen Weg geladenen Entitäten.
using (var db = new NorthwindDb())
{
var shippers = db.Shippers.AsNoTracking()ToList();
foreach (var shipper in shippers)
{
Console.WriteLine("{0} - {1}", shipper.ShipperID, shipper.CompanyName);
}
}
Die Frage ist nun natürlich: Was bringt der Aufruf von AsNoTracking()?
In meinem Beispiel, in dem ich 10.091 Datensätze aus der Tabelle Customers der Northwind Datenbank gelesen habe, konnte ich folgende Werte messen:
Mit Change-Tracking: 10958 ms
Ohne Change Tracking: 9047 ms
Wie wir sehen, spart der Einsatz von AsNoTracking im vorliegenden Fall knapp 2 Sekunden.
Natürlich ist das immer noch nicht sonderlich schnell. Deshalb habe ich einen weiteren Tipp im E-Book veröffentlicht, der ein weiteres, häufiges Problem beim Datenzugriff mit dem Entity Framework behandelt. Wer wissen möchte wie er lautet, sollte einen Blick ins E-Book werfen :-)
Vor einiger Zeit habe ich übrigens ein kleines Video aufgezeichnet, in dem ich die generelle Vorgehensweise beim Performance Profiling mit dem ANTS Performance Profiler erkläre. Wer sich also unsicher ist, warum die eigene Anwendung zu langsam ist, der sollte hier einmal einen Blick rein werfen.
Ihr habt auch tolle Performance Tipps? Dann schreibt ihn doch in einen Kommentar zu diesem Post!