{"id":757,"date":"2020-11-11T23:13:03","date_gmt":"2020-11-11T22:13:03","guid":{"rendered":"https:\/\/www.steffen-liersch.de\/content\/de\/?p=757"},"modified":"2025-03-02T11:29:29","modified_gmt":"2025-03-02T10:29:29","slug":"liersch-reflection","status":"publish","type":"post","link":"https:\/\/www.steffen-liersch.de\/content\/de\/2020\/11\/liersch-reflection\/","title":{"rendered":"Liersch.Reflection &#8211; .NET-Bibliothek f\u00fcr bessere Performance"},"content":{"rendered":"<p>.NET bietet mit der Reflection-API eine einfache M\u00f6glichkeit, zur Laufzeit auf Typen und deren Elemente zuzugreifen. Typische Anwendungsf\u00e4lle sind die Serialisierung und die Deserialisierung von Objekten. Bei der Serialisierung werden mit Hilfe der Reflection-API alle relevanten Felder und Eigenschaften eines Objektes in eine speicherbare Form wie JSON oder XML \u00fcberf\u00fchrt. Die Deserialisierung stellt ein Objekt aus dieser speicherbaren Form wieder her.<\/p>\n<p>Der Preis f\u00fcr das sp\u00e4te Binden von Typen und Elementen zur Laufzeit ist eine geringere Performance. Operationen, die normalerweise durch den Compiler erledigt werden, m\u00fcssen bei Verwendung der Reflection-API zur Laufzeit erfolgen.<\/p>\n<p><code>Liersch.Reflection<\/code> verbessert die Performance der Reflection-API signifikant, indem f\u00fcr Konstruktor- und Funktionsaufrufe, sowie f\u00fcr Feldzugriffe dynamischer IL-Code erzeugt wird. Die Zugriffsgeschwindigkeit gleicht dadurch fast einem Direktzugriff. Es werden alle wichtigen .NET-Plattformen unterst\u00fctzt (ab .NET Framework 2.0, ab .NET Core 2.0 und ab .NET Standard 2.1). F\u00fcr \u00e4ltere Projekte (vor .NET Framework 4.0) muss die Bibliothek manuell kompiliert und integriert werden.<\/p>\n<p>Die Qualit\u00e4t der Bibliothek wird durch automatisierte Modultests sichergestellt. F\u00fcr relevante Funktionen sind Modultests hinterlegt. Alle wesentlichen Bibliotheks\u00e4nderungen werden in der Datei <a href=\"https:\/\/github.com\/steffen-liersch\/Liersch.Reflection\/blob\/master\/CHANGELOG.md\">CHANGELOG.md<\/a> protokolliert.<\/p>\n<h2>Features<\/h2>\n<p><code>Liersch.Reflection<\/code> ist auf die Serialisierung und Deserialisierung von Objekten spezialisiert und stellt daf\u00fcr die folgenden Features bereit:<\/p>\n<ul>\n<li>schnelle Erzeugung von Klassen mit Hilfe des Standardkonstruktors<\/li>\n<li>schnelle Erzeugung von Wertetypen<\/li>\n<li>schnelles Aufrufen von Funktionen<\/li>\n<li>schnelles Lesen und Schreiben von Eigenschaften<\/li>\n<li>schnelles Lesen und Schreiben von Feldern<\/li>\n<\/ul>\n<p>Die Bibliothek ist in C# 6.0 geschrieben. Die Dateigr\u00f6\u00dfe der kompilierten Bibliothek betr\u00e4gt lediglich \u224820 kB.<\/p>\n<h2>Beispiel<\/h2>\n<p>Die Beispielanwendung verwendet <a href=\"https:\/\/github.com\/steffen-liersch\/Liersch.Profiling\">Liersch.Profiling<\/a>, um die Performance verschiedener Szenarien miteinander zu vergleichen. Die Messergebnisse zeigen den Geschwindigkeitsvorteil, der mit <code>Liersch.Reflection<\/code> erzielt werden kann. Die Performancemessung sollte au\u00dferhalb der Entwicklungsumgebung und auf Basis der Release-Version durchgef\u00fchrt werden. Andernfalls beeinflusst der f\u00fcr das Debugging notwendige Zusatzaufwand das Messergebnis.<\/p>\n<h2>Integration<\/h2>\n<p><code>Liersch.Reflection<\/code> beinhaltet die Klasse <code>Accelerator<\/code>, mit deren Hilfe Funktionszeiger f\u00fcr die schnelle Erzeugung von Typen, das schnelle Aufrufen von Funktionen und das schnelle Lesen und Schreiben von Eigenschaften und Feldern erzeugt werden k\u00f6nnen.<\/p>\n<p>Statt Objekte mit <code>Activator.CreateInstance<\/code> zu erzeugen, muss nun der von <code>Accelerator.CreateStandardConstructor<\/code> gelieferte Funktionszeiger benutzt werden, um neue Instanzen zu erzeugen.<\/p>\n<pre><code class=\"language-cs\">Func0 create=Accelerator.CreateStandardConstructor(type);\n\/\/ ...\nobject inst=create();<\/code><\/pre>\n<p>Des Weiteren stehen einige ausgew\u00e4hlte Funktionen der <code>Accelerator<\/code>-Klasse alternativ als Erweiterungsfunktionen mit einer vereinfachten Signatur zur Verf\u00fcgung.<\/p>\n<pre><code class=\"language-cs\">InvocationDelegate toLower=typeof(string).CreateInvocationDelegate(&quot;ToLowerInvariant&quot;);\n\/\/ ...\nobject o=toLower(&quot;Hello World!&quot;);<\/code><\/pre>\n<p>F\u00fcr Funktionen mit bis zu zwei Parametern sind spezialisierte Funktionen verf\u00fcgbar, die f\u00fcr die Parameter\u00fcbergabe kein Array verwenden. Wenn nicht statische Funktionen aufgerufen werden, repr\u00e4sentiert der erste Parameter stets die zu verwendende Instanz. F\u00fcr die Manipulation von Wertetypen m\u00fcssen diese vorher durch Boxing in den Heap-Speicher bef\u00f6rdert werden (z. B. durch Typumwandlung nach <code>object<\/code>). Nur so ist sichergestellt, dass die Manipulationsfunktionen stets das gleiche Objekt bearbeiten und nicht bei jedem Zugriff eine neue Kopie verwenden. Eine Unterst\u00fctzung von per Verweis \u00fcbergebenen Parametern (siehe Schl\u00fcsselwort <code>ref<\/code> und <code>out<\/code>) ist nicht vorgesehen.<\/p>\n<p>Die Verbesserung der Performance von Reflection-basierten Zugriffen erfolgt auf Basis von dynamisch generiertem Code. Der Aufwand der Codegenerierung lohnt sich nur dann, wenn eine h\u00f6here Anzahl von Zugriffen erwartet wird.<\/p>\n<h2>Lizenz<\/h2>\n<p>Die Ver\u00f6ffentlichung der Software erfolgt unter den Bedingungen einer Open-Source-Lizenz. Alternativ k\u00f6nnen im Rahmen einer kommerziellen Lizenz andere Bedingungen vereinbart werden. Sie k\u00f6nnen Pflege und Weiterentwicklung der Software mit einer <a href=\"https:\/\/www.paypal.com\/cgi-bin\/webscr?cmd=_s-xclick&amp;hosted_button_id=NVXEQCNGJFK92\">freiwilligen Spende<\/a> unterst\u00fctzen.<\/p>\n<h2>Copyright<\/h2>\n<p>Copyright \u00a9 2020-2021 Steffen Liersch<br \/>\n<a href=\"https:\/\/www.steffen-liersch.de\/\">https:\/\/www.steffen-liersch.de\/<\/a><\/p>\n<h2>Verweise<\/h2>\n<p>Der Quellcode wird auf GitHub gepflegt:<br \/>\n<a href=\"https:\/\/github.com\/steffen-liersch\/Liersch.Reflection\">https:\/\/github.com\/steffen-liersch\/Liersch.Reflection<\/a><\/p>\n<p>Pakete k\u00f6nnen \u00fcber NuGet heruntergeladen werden:<br \/>\n<a href=\"https:\/\/www.nuget.org\/packages\/Liersch.Reflection\">https:\/\/www.nuget.org\/packages\/Liersch.Reflection<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Liersch.Reflection verbessert die Performance der Reflection-API signifikant, indem f\u00fcr Konstruktor- und Funktionsaufrufe, sowie f\u00fcr Feldzugriffe dynamischer IL-Code erzeugt wird. Die Zugriffsgeschwindigkeit gleicht dadurch fast einem Direktzugriff. Es werden alle wichtigen .NET-Plattformen unterst\u00fctzt (ab .NET Framework 2.0, ab .NET Core 2.0 und ab .NET Standard 2.1).<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[5],"tags":[21,25,36,31],"class_list":["post-757","post","type-post","status-publish","format-standard","hentry","category-net","tag-net","tag-cs","tag-open-source","tag-products"],"_links":{"self":[{"href":"https:\/\/www.steffen-liersch.de\/content\/de\/wp-json\/wp\/v2\/posts\/757","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.steffen-liersch.de\/content\/de\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.steffen-liersch.de\/content\/de\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.steffen-liersch.de\/content\/de\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.steffen-liersch.de\/content\/de\/wp-json\/wp\/v2\/comments?post=757"}],"version-history":[{"count":13,"href":"https:\/\/www.steffen-liersch.de\/content\/de\/wp-json\/wp\/v2\/posts\/757\/revisions"}],"predecessor-version":[{"id":835,"href":"https:\/\/www.steffen-liersch.de\/content\/de\/wp-json\/wp\/v2\/posts\/757\/revisions\/835"}],"wp:attachment":[{"href":"https:\/\/www.steffen-liersch.de\/content\/de\/wp-json\/wp\/v2\/media?parent=757"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.steffen-liersch.de\/content\/de\/wp-json\/wp\/v2\/categories?post=757"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.steffen-liersch.de\/content\/de\/wp-json\/wp\/v2\/tags?post=757"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}