Das Übergeben als in
Referenz scheint logisch dem Übergeben als Wert zu entsprechen.
Richtig.
Gibt es einen Leistungsvorteil?
Ja.
Ich war der Überzeugung, dass ein ref
Parameter auf der Back-End-Seite mindestens die physische Adresse der Variablen kopieren muss, die dieselbe Größe wie jede typische Objektreferenz haben sollte.
Es gibt keine Anforderung, dass eine Referenz auf ein Objekt und eine Referenz auf eine Variable beide dieselbe Größe haben, und es gibt keine Anforderung, dass beide die Größe eines Maschinenworts haben, aber ja, in der Praxis sind beide 32 Bit auf 32 Bitmaschinen und 64-Bit auf 64-Bit-Maschinen.
Was Ihrer Meinung nach die "physische Adresse" damit zu tun hat, ist mir unklar. Unter Windows verwenden wir virtuelle Adressen , keine physischen Adressen im Benutzermoduscode. Unter welchen möglichen Umständen würden Sie sich vorstellen, dass eine physikalische Adresse in einem C # -Programm von Bedeutung ist? Ich bin neugierig zu wissen.
Es ist auch nicht erforderlich, dass eine Referenz jeglicher Art als virtuelle Adresse des Speichers implementiert wird. Referenzen könnten undurchsichtige Handles in GC-Tabellen in einer konformen Implementierung der CLI-Spezifikation sein.
ist der Vorteil nur bei größeren Strukturen?
Das Motivationsszenario für das Feature besteht darin, die Kosten für das Übergeben größerer Strukturen zu senken .
Beachten Sie, dass es keine Garantie gibt, in
die ein Programm tatsächlich schneller macht, und dass es Programme langsamer machen kann. Alle Fragen zur Leistung müssen durch empirische Forschung beantwortet werden . Es gibt nur sehr wenige Optimierungen, die immer gewinnen . Dies ist keine "immer gewinnen" -Optimierung.
Gibt es eine Compiler-Optimierung hinter den Kulissen, die es anderswo attraktiv macht?
Der Compiler und die Laufzeit dürfen jede von ihnen gewählte Optimierung vornehmen, wenn dies nicht gegen die Regeln der C # -Spezifikation verstößt. Es gibt meines Wissens noch keine solche Optimierung für in
Parameter, aber das schließt solche Optimierungen in Zukunft nicht aus.
Warum sollte ich nicht jeden Parameter zu einem In machen?
Angenommen, Sie haben int
stattdessen einen in int
Parameter als Parameter festgelegt. Welche Kosten fallen an?
- Die Aufrufsite benötigt jetzt eine Variable anstelle eines Werts
- Die Variable kann nicht registriert werden. Das sorgfältig abgestimmte Registerzuordnungsschema des Jitters hat gerade einen Schraubenschlüssel hineingeworfen.
- Der Code an der Aufrufstelle ist größer, da er einen Verweis auf die Variable nehmen und diesen auf den Stapel legen muss, während er zuvor einfach den Wert auf den Aufrufstapel übertragen konnte
- Größerer Code bedeutet, dass einige Kurzsprunganweisungen möglicherweise zu Weitsprunganweisungen geworden sind. Daher ist der Code jetzt wieder größer. Dies hat Auswirkungen auf alle möglichen Dinge. Caches werden früher gefüllt, der Jitter hat mehr Arbeit zu erledigen, der Jitter kann sich dafür entscheiden, bestimmte Optimierungen bei größeren Codegrößen nicht vorzunehmen, und so weiter.
- Auf der Angerufenen-Site haben wir den Zugriff auf einen Wert auf dem Stapel (oder Register) in eine Indirektion in einen Zeiger umgewandelt. Nun, dieser Zeiger befindet sich höchstwahrscheinlich im Cache, aber wir haben jetzt einen Ein-Befehl-Zugriff auf den Wert in einen Zwei-Befehl-Zugriff umgewandelt.
- Und so weiter.
Angenommen, es ist ein double
und Sie ändern es in ein in double
. Auch hier kann die Variable jetzt nicht mehr in ein Hochleistungs-Gleitkommaregister eingetragen werden. Dies hat nicht nur Auswirkungen auf die Leistung , sondern kann auch das Programmverhalten ändern! C # darf Float-Arithmetik mit einer Genauigkeit von mehr als 64 Bit ausführen und dies normalerweise nur, wenn die Floats registriert werden können.
Dies ist keine kostenlose Optimierung. Sie müssen die Leistung an den Alternativen messen. Ihre beste Wahl ist es, überhaupt keine großen Strukturen zu erstellen, wie es die Designrichtlinien vorschlagen.
ref
wird verwendet, um Strukturen als Referenz zu übergeben, anstatt sie zu kopieren.in
bedeutet, dass die Struktur nicht geändert werden sollte.