2013-10-08 6 views
9

In dieser Diskussion über die Performance-Overhead der Verwendung reflection verwenden, heißt es:Welche Art von Laufzeitoptimierungen gehen verloren, wenn wir Reflexion

Verwendung von Reflexion einiger Laufzeitoptimierungen verloren verursachen. Beispielsweise wird der folgende Code sehr wahrscheinlich durch eine virtuelle Java-Maschine optimiert werden:

int x = 1; 
x = 2; 
x = 3; 

Equivalent Code Field.set * mit() nicht.

Ohne Reflektion, welche Art von Laufzeitoptimierungen würde JVM vornehmen?

+0

Es würde einfach 'x = 3' laufen. Alle Arten von Inlining-Tricks, Opcode-Eliminierung usw. verschwinden, wenn Sie Reflektion in den Mix werfen. –

+0

Das ist eine interessante Frage, aber ich denke, es ist zu breit für eine einzige SO-Frage. – chrylis

+0

Die Zuweisungen zu x tun nichts. Es ist eine lokale Variable, kein Multi-Thread, keine Parallelität und kann entfernt werden. Wenn Sie Field.set verwenden, kann ein anderer Thread Zugriff auf die Variable haben, so dass sie niemals optimiert werden kann. Das ist was ich denke. –

Antwort

0

Viele JIT-Optimierungen können nicht durchgeführt werden. Sehen Sie sich einfach die JDK-Quelle an, setzen Sie einen Feldwert über die Reflektion, um Sicherheitsprüfungen und einige Suchvorgänge durchzuführen.

Während direkter Code auf primitiven Werten, wie von Ihrer Frage umrissen, zu einigen Assemblierungsanweisungen gesendet wird, geben Reflektionsaufrufe dem Optimierer nur sehr wenige Informationen darüber, was vor sich geht, so dass wenig Optimierungen vorgenommen werden können.

Wenn Sie es benchmarken, werden Sie feststellen, dass die Reflexion eine Größenordnung ist, die im Vergleich zu "direktem" Code langsamer ist.

+1

Können Sie Ihre letzte Zeile näher erläutern? Wie sind Sie zu der Schlussfolgerung der "Größenordnung" gekommen? – Victor

+0

Reflection kann fast so schnell sein wie direkter Code, je nachdem, was Sie tun und wie Sie es tun. Insbesondere haben die Sicherheitskontrollen usw. nur Auswirkungen auf den ersten Zugriff ... – assylias

+0

Testen Sie es einfach. (1) Führen Sie eine anständige Aufwärmphase (> 10000 Iterationen) durch, so dass JIT einsetzt. Vermeiden Sie einen "loop-in-place-jitting" -Fehlschein. –

3

In diesem Fall kann der Code verworfen werden, da er scheinbar nichts zu tun hat.

Wenn Sie Reflexion verwendet haben, vermute ich, dass es immer noch etwas tun würde, obwohl Sie nicht auf eine lokale Variable mit Reflektion zugreifen können.

Verwandte Themen