Letztens musste ich eine persönliche Niederlage einstecken. Normalerweise ist ein handgeschriebener Data Acces Layer,
welcher mit ADO.NET Sql-Statements auf einer Datenbank ausführt und das Resultset über einen DbDataReader abruft extrem schnell und die meisten ORMs können sich damit unter Performanceaspekten nicht messen. Die Betonung liegt auf “normalerweise”. Letzte Woche wurde ich von einem meiner Kollegen eines Besseren belehrt.
Der manuell geschriebene Code hat zuerst alle Ordinals zu den Spaltennamen ermittelt, damit dies beim Abruf der Datensätze nicht bei jeder Zeile implizit gemacht werden muss wie es beim direkten Zugriff mit Spaltennamen der Fall wäre. Gerade bei Resultsets mit vielen Spalten kommt dabei ein recht uneleganter Code heraus.
Mein Kollege hat den Versuch gestartet und die handgeschriebe Implementierung gegen den leichtgewichtigen ORM “Dapper.NET” von StackOverflow ersetzt. Der Code wurde so von etwa 60 Zeilen auf eine Zeile reduziert.
Der neue Code sieht nun wie im Beispiel auf der Dapper.NET Seite aus:
var dogList = connection.Query<Dog>("select Age = @Age, Id = @Id", new { Age = (int?)null, Id = Guid.NewGuid() });
Über eine anonyme Klasse werden die Parameter auf sehr elegante Weise deklariert. Der Typ, in den die Datensätze gemappt werden sollen, wird als generischer Parameter angegeben.
Die Lösung hat mir auf Anhieb richtig gut gefallen. Aber was glauben Sie was mein erster Einwand war? An dieser Stelle kommt es auf Performance an und ich konnte mir nicht vorstellen, dass dieser generische, elegante Ansatz meinen handgeschriebenen Code in dieser Disziplin schlagen konnte.
Mein Kollege und ich haben uns also zusammengesetzt und jeweils drei Performance-Messungen mit der alten und mit der neuen Implementierung gemacht. Das Resultset war etwa 750 Zeilen mit 30 Spalten gross. Das Ergebnis konnte ich zuerst nicht glauben. Mein Code war ganze 20 Millisekunden langsamer als die Dapper Implementierung.
Ein Blick hinter die Kullisen erklärt das Phänomen jedoch:
Die Dapper.NET Implementierung ist bis ins Detail getunt. Die hohe Performance wird durch dynamisch kompilierte, an die Daten angepasste, Methoden erreicht. Auch über die Code-Qualität muss man sich keine Sorgen machen, da genau dieses Stück Code bei StackOverflow in Produktion läuft und täglich hunderttausende Anfragen bearbeitet.
Insgesamt hat mich diese Implementierung restlos begeistert und ich bin mir sicher, dass mir dieses geniale Stück Code noch in vielen Projekten gute Dienste leisten wird.
Den Source-Code sowie einige Beispiele finden Sie unter: http://code.google.com/p/dapper-dot-net/

