Die Syntax und Semantik sind bereits in anderen hervorragenden Antworten auf diese Frage gut definiert. Denn Ausführung y Leistung nicht gut beschrieben sind, werde ich meine Antwort hinzufügen.
Was ist der funktionale Unterschied zwischen diesen 3?
Ich hatte Atom als Standard immer als ziemlich merkwürdig angesehen. Auf der Abstraktionsebene, auf der wir arbeiten, ist die Verwendung atomarer Eigenschaften für eine Klasse als Mittel zum Erreichen einer 100 %igen Thread-Sicherheit ein Eckfall. Für wirklich korrekte Multithreading-Programme ist das Eingreifen des Programmierers mit Sicherheit eine Voraussetzung. In der Zwischenzeit sind die Leistungsmerkmale und die Ausführung noch nicht im Detail erforscht worden. Nachdem ich im Laufe der Jahre einige stark multithreading-fähige Programme geschrieben hatte, deklarierte ich meine Eigenschaften als nonatomic
die ganze Zeit, weil Atomkraft für keinen Zweck sinnvoll war. Während der Diskussion über die Einzelheiten der atomaren und nichtatomaren Eigenschaften diese Frage habe ich einige Profile erstellt und bin dabei auf einige merkwürdige Ergebnisse gestoßen.
Ausführung
Okay. Das erste, was ich klarstellen möchte, ist, dass die Sperrimplementierung implementierungsdefiniert und abstrahiert ist. Louis verwendet @synchronized(self)
in seinem Beispiel - ich habe gesehen, dass dies eine häufige Quelle der Verwirrung ist. Die Implementierung ist nicht eigentlich verwenden. @synchronized(self)
; es verwendet die Objektebene Spinlocks . Die Illustration von Louis eignet sich gut für eine Veranschaulichung auf hohem Niveau unter Verwendung von Konstrukten, die uns allen vertraut sind, aber es ist wichtig zu wissen, dass sie keine @synchronized(self)
.
Ein weiterer Unterschied ist, dass atomare Eigenschaften den Zyklus Ihrer Objekte innerhalb des Getters beibehalten/freigeben.
Leistung
Jetzt kommt der interessante Teil: Die Leistung bei atomaren Eigenschaftszugriffen in unbestritten (z.B. Single-Thread) kann in einigen Fällen wirklich sehr schnell sein. In weniger idealen Fällen kann die Verwendung von atomaren Zugriffen mehr als das 20-fache des Overheads von nonatomic
. Während die Umstritten Fall mit 7 Threads war 44 Mal langsamer für die Drei-Byte-Struktur (2,2 GHz) Kern i7 Quad Core, x86_64). Die Drei-Byte-Struktur ist ein Beispiel für eine sehr langsame Eigenschaft.
Interessante Randbemerkung: Die benutzerdefinierten Zugriffsfunktionen der Drei-Byte-Struktur waren 52 Mal schneller als die synthetisierten atomaren Zugriffsfunktionen oder 84 % schneller als die synthetisierten nichtatomaren Zugriffsfunktionen.
In strittigen Fällen können die Objekte auch das 50-fache überschreiten.
Aufgrund der Vielzahl der Optimierungen und der unterschiedlichen Implementierungen ist es recht schwierig, die Auswirkungen in der Praxis zu messen. Oft hört man etwas wie "Vertrauen Sie darauf, es sei denn, Sie erstellen ein Profil und stellen fest, dass es ein Problem ist". Aufgrund der Abstraktionsebene ist es tatsächlich recht schwierig, die tatsächlichen Auswirkungen zu messen. Die Ermittlung der tatsächlichen Kosten aus den Profilen kann sehr zeitaufwändig und aufgrund der Abstraktionsebene recht ungenau sein. Auch der Unterschied zwischen ARC und MRC kann einen großen Unterschied ausmachen.
Lassen Sie uns also einen Schritt zurücktreten, no Da wir uns auf die Implementierung von Eigenschaftszugriffen konzentrieren, werden wir die üblichen Verdächtigen einbeziehen, wie objc_msgSend
und untersuchen einige praktische Ergebnisse für viele Aufrufe einer NSString
Getter in unbestritten Fälle (Werte in Sekunden):
- MRC | nonatomic | manuell implementierte Getter: 2
- MRC | nonatomic | synthesized getter: 7
- MRC | atomic | synthesized getter: 47
- ARC | nonatomic | synthesized getter: 38 (Hinweis: ARC fügt hier die Anzahl der Referenzen hinzu)
- ARC | atomic | synthesized getter: 47
Wie Sie wahrscheinlich schon vermutet haben, ist die Referenzzahlaktivität/der Zyklus ein wichtiger Faktor bei Atomkraftwerken und unter ARC. Größere Unterschiede sind auch bei strittigen Fällen zu beobachten.
Obwohl ich sehr auf die Leistung achte, sage ich immer noch Semantik zuerst! . In der Zwischenzeit hat die Leistung bei vielen Projekten eine geringe Priorität. Es kann jedoch nicht schaden, die Ausführungsdetails und Kosten der von Ihnen verwendeten Technologien zu kennen. Sie sollten die richtige Technologie für Ihre Bedürfnisse, Zwecke und Fähigkeiten einsetzen. Hoffentlich erspart Ihnen dies einige Stunden des Vergleichens und hilft Ihnen, bei der Entwicklung Ihrer Programme eine fundierte Entscheidung zu treffen.
4 Stimmen
developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/