2009-07-17 5 views
18

Ich versuche, die Leistungseinbußen bei der Kommunikation über AppDomains auf demselben Computer zu minimieren. In meinem Spielzeugbeispiel wird Klasse A in AppDomain 1 geladen. Es erstellt eine AppDomain 2 und lädt dort eine Instanz der Klasse 2 (Klasse 2 erbt von MarshalByRef) und erhält einen Proxy zurück. Dann ruft Klasse 1 wiederholt eine Methode auf dem Proxy auf, die keine Werte zurückgibt.Wie hoch ist die Mindestleistung für die Cross AppDomain-Kommunikationsleistung?

ich folgende Ergebnisse:

  1. Keine AppDomains werden beide Klassen in derselben AppDomain geladen und die ersten Anrufe repetedly die Methode auf dem zweiten (die Methode keine Parameter): 24 Millionen Verfahren Anrufe/sec
  2. zwei AppDomain wie oben beschrieben, hat Methode keine Parameter oder String-Parameter "Ausbluten": 340.000 Methoden aufrufen/sec
  3. zwei AppDomains wie oben beschrieben, ein serializable Parameter (Array von zwei String e): 64.000 Methodenaufrufe/sec

Obwohl ich die Leistungseinbuße zwischen 2 und 3 (Serialisierung) verstehen, ich verstehe wirklich nicht, warum ich 100-mal langsamer bin von Fall 1 bis Fall 2 . Nach dem Erstellen des Proxys müssen alle nachfolgenden Methodenaufrufe wirklich schnell sein, da keine Daten von einer AppDomain zu einer anderen AppDomain gemarshallt werden. Hat jemand jetzt die Kommunikation über AppDomains so langsam? Mache ich etwas falsch?

PS1. Der einzige Tipp, den ich hier habe, ist here: "Und die Kosten für das Überqueren einer AppDomain-Grenze ist peinlich." Ich vermutete, er bezieht sich auf die Serialisierung ...

PS2. Ich zähle die AppDomain- oder Proxy-Erstellungszeit nicht (meine Benchmarks beginnen im ersten Methodenaufruf)

PS3. Ich verwende .NET 3.5 in einer WinXP SP3-Maschine. Ich habe auch .NET 4.0 Beta 1 ohne wesentliche Unterschiede versucht.

Antwort

11

Wenn Sie Zeilen von IL, die in jedem Szenario beteiligt sind, zählen, werden Sie sehen, dass die CLR viel mehr als das 100-fache der Arbeit beim Remoting leistet. Ein direkter Aufruf ist nur ein paar Opcodes, aber beim Remoting sind mehrere Klassen beteiligt, echte/transparente Proxies, Sicherheitschecks, Serialisierung, yadda yadda yadda. Sie müssen dies durch Design angehen - es gibt kein Wundermittel zur Verbesserung der Perf-Implementierung.

+1

+1 Ich stimme Ihnen vollkommen zu. Ein einfacher direkter Methodenaufruf ist extrem einfach. Ein Methodenaufruf durch ** Remoting ** ist viel schwerer. Der Overhead ist viel größer. Die einzige wirkliche Lösung ist ein gutes Anwendungsdesign, das nicht von der Geschwindigkeit der übergreifenden AppDomain-Kommunikation abhängt. – jpbochi

1

Gibt es eine Möglichkeit, eine einzelne Hilfsmethode aufzurufen, die Parameter dazu verwendet, wie oft Sie die Methode aufrufen möchten, die Sie benötigen? Die Leistung von Cross-AppDomain-Anrufen hängt von der Implementierung stark ab. Ich glaube, dass es in der CLR 4.0 deutlich besser sein könnte, aber ich kenne mich mit den Details nicht aus.

Im Allgemeinen möchten Sie jedoch den Overhead vermeiden, indem Sie die Aufrufe über eine Hilfsmethode "stapeln".

+0

Ich sehe nicht, wie es mir helfen wird. Die Methode der Klasse A macht genau das: kontinuierlich object.MyMethod() aufrufen.Wenn die Kosten eines Anrufs in einem Proxy wirklich 100 Mal höher sind als bei einem Aufruf für dasselbe AppDomain-Objekt, ist die Auswirkung in meinem Design sehr groß. – Yiannis

+3

Rufen Sie object.MyHelperMethod auf, die object.MyMethod wiederholt in der anderen AppDomain aufruft. Wenn Sie die Leistung benötigen und angenommen haben, dass Cross-AppDomain mit hoher Geschwindigkeit dafür benötigt wird, dann könnte das einen großen Einfluss auf Ihr Design haben. –

+0

Ohh, ich sehe ..! :-) OK, das wird natürlich die Dinge schnell machen. Aber dieses Beispiel ist nur ein Spielzeug, mein echtes Programm wird nicht die gleiche Funktion 20mil mal pro Sekunde nennen ..! Ich werde verschiedene Cross-AppDomain-Aufrufe durchführen müssen, die im Allgemeinen schnell sein müssen. Thnanks sowieso! – Yiannis

0

Ich habe die gleichen Ergebnisse gesehen. Ich kann nicht erklären, warum es so viel langsamer ist, außer dass es schneller ist, als wenn zwei verschiedene Prozesse laufen und miteinander kommunizieren. In meinem Entwurf sah ich mich einem ähnlichen Dilemma gegenüber. Am Ende habe ich mein Design geändert, um unabhängige App-Domains zu erstellen. Die App-Domäne konnte ihre Arbeit erledigen, ohne während der Ausführung mit einer anderen App-Domäne kommunizieren zu müssen ... Sie würde nur nach Abschluss Daten melden.

Verwandte Themen