Jochens Weblog

ESCde Developer Blog

  Home :: Kontakt :: RSS Feed
  12 Posts :: 0 Artikel :: 4 Kommentare :: 0 Trackbacks

Archiv

Post Kategorien

ESCde

ESCde Blogger

Die beiden Schlüsselwörter is und as sollte jeder C#-Programmierer kennen: Mit is kann geprüft werden, ob ein Objekt Instanz eines bestimmten Typs ist. Das Ergebnis dieses Aufrufs ist ein Boolean:

if (a is B) { B b = (B)a; // b verwenden... }

In diesem Beispiel gehe ich davon aus, dass B eine von A abgeleitete Klasse ist. Die Verwendung ist nun recht offensichtlich. Alternativ kann man auch das as-Schlüsselwort verwenden. as gibt sofort das gecastete Objekt zurück, beziehungsweise null, falls der cast nicht durchgeführt werden kann.

B b = a as B; if (b != null) { // b verwenden }

Beide Varianten sehen recht schön aus und gehen schnell von der Hand. Nun stellt sich natürlich die Frage, welche Variante man (üblicherweise) verwenden sollte. Zunächst drängt sich natürlich ein Geschwindigkeitsvergleich auf. Man sollte annehmen, dass dieser Code vom Compiler in identischer Art und Weise übersetzt wird, da (oberflächlich betrachtet) ja eigentlich das Gleiche passiert. Aber weit gefehlt: Der entstehende IL-Code sieht nicht nur unterschiedlich aus, sondern es gibt auch einen klaren Gewinner bezüglich der Ausführungsgeschwindigkeit: as.

Die Begründung hierfür ist recht einfach: In der ersten Variante muss die Runtime beim is Befehl prüfen, ob es sich bei a um ein B-Objekt handelt. Dieser Aufwand ist nahezu identisch mit einem cast. Anschließend wird innerhalb des if-Blocks erneut gecastet. Beim as Befehl selbst wird ebenfalls ein "cast-artiger" Test durchgeführt. Im if-Block allerdings nicht. Daher muss bei der as Variante nur einmal der Typ geprüft werden, bei is zweimal. Der null-Test bei as ist so schnell, dass er kaum ins Gewicht fällt. Testet man dies mit der Stopwatch mal durch,  so sieht man dass as tatsächlich die besseren Ergebnisse liefert. Allerdings sind beide Operatoren sehr schnell, so dass man für alltägliche Anwendungen völlig bedenkenlos is verwenden kann. In einer Performance-kritischen Anwendung, beispielsweise in einem XNA-Projekt, kann ein konsequentes beachten solcher Details sich in der Summe schon lohnen.

Betrachtet man den IL-Code, so sieht man auch schon, dass der is-Code ein wenig länger ist. DIe kritische Anweisung ist hierbei der castclass IL-Befehl, der genau dem cast in der if-Abfrage entspricht und den Performance-Unterschied ausmacht.

veröffentlicht am 02.04.2007 11:25

Kommentare

Bisher kein Feedback.

Kommentar abgeben

Titel:
Name:
Email:
(wird nicht angezeigt!)
Homepage:
Feedback:
Please add 7 and 5 and type the answer here: