La sintassi e la semantica sono già ben definite da altre eccellenti risposte a questa domanda. Poiché l' esecuzione e le prestazioni non sono ben dettagliate, aggiungerò la mia risposta.
Qual è la differenza funzionale tra questi 3?
Ho sempre considerato l'atomico come un default piuttosto curioso. A livello di astrazione su cui lavoriamo, l'utilizzo di proprietà atomiche per una classe come veicolo per ottenere il 100% di sicurezza del filo è un caso angolare. Per programmi multithread veramente corretti, l'intervento del programmatore è quasi certamente un requisito. Nel frattempo, le caratteristiche prestazionali e l'esecuzione non sono state ancora dettagliate in dettaglio. Dopo aver scritto alcuni programmi fortemente multithread nel corso degli anni, avevo dichiarato le mie proprietà per nonatomic
tutto il tempo perché l'atomica non era ragionevole per nessuno scopo. Durante la discussione dei dettagli delle proprietà atomiche e non anatomiche di questa domanda , ho fatto un po 'di profiling incontrando alcuni risultati curiosi.
Esecuzione
Ok. La prima cosa che vorrei chiarire è che l'implementazione di blocco è definita e astratta. Louis usa @synchronized(self)
nel suo esempio: l'ho visto come una fonte comune di confusione. L'implementazione non utilizza effettivamente@synchronized(self)
; utilizza i blocchi di spin a livello di oggetto . L'illustrazione di Louis è buona per un'illustrazione di alto livello che usa costrutti che conosciamo tutti, ma è importante sapere che non li usa @synchronized(self)
.
Un'altra differenza è che le proprietà atomiche manterranno / rilasceranno i tuoi oggetti all'interno del getter.
Prestazione
Ecco la parte interessante: le prestazioni che utilizzano gli accessi alle proprietà atomiche in casi non contestati (ad esempio a thread singolo) possono essere molto veloci in alcuni casi. In casi non ideali, l'uso di accessi atomici può costare oltre 20 volte il sovraccarico di nonatomic
. Mentre il caso contestato con 7 thread era 44 volte più lento per la struttura a tre byte (2,2 GHz Core i7 Quad Core, x86_64). La struttura a tre byte è un esempio di una proprietà molto lenta.
Nota a margine interessante: gli accessori definiti dall'utente della struttura a tre byte erano 52 volte più veloci degli accessori atomici sintetizzati; o l'84% della velocità degli accessori non anatomici sintetizzati.
Anche gli oggetti nei casi contestati possono superare 50 volte.
A causa del numero di ottimizzazioni e variazioni nelle implementazioni, è abbastanza difficile misurare gli impatti del mondo reale in questi contesti. Potresti spesso sentire qualcosa del tipo "Fidati, a meno che non ti profilassi e trovi che è un problema". A causa del livello di astrazione, in realtà è abbastanza difficile misurare l'impatto reale. Raccogliere i costi effettivi dai profili può richiedere molto tempo e, a causa delle astrazioni, abbastanza impreciso. Inoltre, ARC vs MRC può fare la differenza.
Quindi facciamo un passo indietro, non concentrandoci sull'implementazione degli accessi alle proprietà, includeremo i soliti sospetti come objc_msgSend
ed esamineremo alcuni risultati di alto livello del mondo reale per molte chiamate a un NSString
getter in casi non contestati (valori in secondi):
- MRC | non anatomico | Getter implementati manualmente: 2
- MRC | non anatomico | getter sintetizzato: 7
- MRC | atomico | getter sintetizzato: 47
- ARC | non anatomico | getter sintetizzato: 38 (nota: l'ARC sta aggiungendo il conteggio dei riferimenti in bicicletta qui)
- ARC | atomico | getter sintetizzato: 47
Come probabilmente avete indovinato, l'attività di conteggio dei riferimenti / ciclismo è un contributo significativo con l'atomica e sotto ARC. Vedresti anche maggiori differenze nei casi contestati.
Anche se prendo molta attenzione alle prestazioni, dico ancora Semantics First! . Nel frattempo, le prestazioni sono una priorità bassa per molti progetti. Tuttavia, conoscere i dettagli di esecuzione e i costi delle tecnologie che usi sicuramente non fa male. Dovresti usare la tecnologia giusta per le tue esigenze, scopi e capacità. Spero che questo ti risparmierà qualche ora di confronto e ti aiuti a prendere una decisione più informata durante la progettazione dei tuoi programmi.