Dynamisch kompilierten C # -Code mit nativer Geschwindigkeit ausführen ... wie?

8

Ich habe mehrere Beiträge zu SO über das Schreiben und Kompilieren von dynamischem C # -Code gelesen. Zum Beispiel diesen Beitrag . Ich verstehe, dass es mehrere Möglichkeiten gibt.

Das Aufrufen des Code-Aufrufers ist jedoch langsam. Ich habe einen einfachen Benchmark gemacht, und es ist ungefähr 500 X langsamer als eine native Methode aufzurufen.

Was ich tun kann, ist das Äquivalent, eine DLL zu laden und eine ihrer Methoden direkt aufzurufen ("nativ"), was die gewünschten Geschwindigkeitsvorteile bringt.

Was ist der einfachste Weg, dies zu tun? Kompiliere den dynamischen Code zu einer DLL und lade sie dann? Kann es im Speicher gemacht werden?

BEARBEITEN

Ich kümmere mich nicht um die Kompilierungszeit. Nur Ausführung.

BEARBEITEN 2, 3

Hier ist der Benchmarkcode, den ich geschrieben habe:

%Vor%     
IamIC 16.05.2012, 07:17
quelle

3 Antworten

7

Ja, wenn Sie über eine MethodInfo oder eine unspezifische Delegate aufrufen, wird es in der Tat langsam sein. Der Trick ist: tu das nicht . Verschiedene Ansätze:

  • für einzelne Methoden, gehen Sie über einen einfachen aber typisierten Delegaten wie Action oder als generischen Catch-all, Func<object[], object> - und verwenden Sie Delegate.CreateDelegate , um einen getippter Delegierter:

    %Vor%

    Eine andere Variante ist die Verwendung der Expression API (welche eine .Compile() Methode hat) oder DynamicMethod (welche CreateDelegate() hat). Das Wichtigste: Sie müssen einen typisierten Delegaten abrufen und ihn mit typisiert aufrufen (nicht .DynamicInvoke ).

  • Für komplexere Fälle, in denen Sie ganze Typen generieren, sollten Sie eine Schnittstelle implementieren, die Sie kennen, z. B.

    %Vor%

    nochmal; Nach der ersten Besetzung (die sehr billig ist) können Sie einfach statischen Code verwenden:

    %Vor%

Verwenden Sie nicht someDelegate.DynamicInvoke(...) oder someMethod.Invoke(...) , wenn Sie nach irgendeiner Art von Leistung suchen.

    
Marc Gravell 16.05.2012, 07:31
quelle
3

Neben Marcs Ratschlag könnte man die Geschwindigkeit verbessern, indem man die Compileroption "optimieren" angibt:

%Vor%     
Bond 16.05.2012 08:07
quelle
1

Ich dachte, es wäre es wert gewesen, zu zeigen, wie alle möglichen Optionen aussahen und ihre Leistungsmerkmale. Gegeben die folgenden Hilfsklassen und Funktionen:

%Vor%

Einrichtung und Ausführung:

%Vor%

Die Ergebnisse sind:

%Vor%

In den Fällen, in denen Sie keine Delegierten verwenden können (wenn Sie nicht genug wissen?), können Sie dynamic ausprobieren.

    
yamen 16.05.2012 08:31
quelle