La sintaxis y la semántica ya están bien definidas por otras excelentes respuestas a esta pregunta. Como la ejecución y el rendimiento no están bien detallados, agregaré mi respuesta.
¿Cuál es la diferencia funcional entre estos 3?
Siempre había considerado atómico como un defecto bastante curioso. En el nivel de abstracción en el que trabajamos, el uso de propiedades atómicas para una clase como vehículo para lograr un 100% de seguridad de roscas es un caso de esquina. Para programas multiproceso verdaderamente correctos, la intervención del programador es casi un requisito. Mientras tanto, las características de rendimiento y ejecución aún no se han detallado en profundidad. Habiendo escrito algunos programas muy multiproceso a lo largo de los años, había estado declarando mis propiedades nonatomic
todo el tiempo porque atomic no era sensato para ningún propósito. Durante la discusión de los detalles de las propiedades atómicas y no atómicas de esta pregunta , hice algunos perfiles y encontré algunos resultados curiosos.
Ejecución
Okay. Lo primero que me gustaría aclarar es que la implementación de bloqueo está definida y resumida en la implementación. Louis usa @synchronized(self)
en su ejemplo: he visto esto como una fuente común de confusión. La implementación en realidad no usa @synchronized(self)
; utiliza bloqueos de giro a nivel de objeto . La ilustración de Louis es buena para una ilustración de alto nivel que utiliza construcciones con las que todos estamos familiarizados, pero es importante saber que no se usa @synchronized(self)
.
Otra diferencia es que las propiedades atómicas retendrán / liberarán el ciclo de sus objetos dentro del captador.
Actuación
Aquí está la parte interesante: el rendimiento mediante el acceso a propiedades atómicas en casos no disputados (por ejemplo, de un solo subproceso) puede ser realmente muy rápido en algunos casos. En casos menos que ideales, el uso de accesos atómicos puede costar más de 20 veces la sobrecarga de nonatomic
. Mientras que el caso impugnado con 7 subprocesos fue 44 veces más lento para la estructura de tres bytes ( Core i7 Quad Core de 2.2 GHz , x86_64). La estructura de tres bytes es un ejemplo de una propiedad muy lenta.
Nota al margen interesante: los accesores definidos por el usuario de la estructura de tres bytes fueron 52 veces más rápidos que los accesos atómicos sintetizados; o 84% de la velocidad de los accesos no atómicos sintetizados.
Los objetos en casos disputados también pueden exceder 50 veces.
Debido a la cantidad de optimizaciones y variaciones en las implementaciones, es bastante difícil medir los impactos del mundo real en estos contextos. A menudo puede escuchar algo como "Confía en él, a menos que hagas un perfil y descubras que es un problema". Debido al nivel de abstracción, en realidad es bastante difícil medir el impacto real. Obtener los costos reales de los perfiles puede llevar mucho tiempo y, debido a las abstracciones, ser bastante inexactos. Además, ARC vs MRC puede hacer una gran diferencia.
Entonces, retrocedamos, sin centrarnos en la implementación de accesos a la propiedad, incluiremos los sospechosos habituales objc_msgSend
, y examinaremos algunos resultados de alto nivel del mundo real para muchas llamadas a un NSString
captador en casos no controvertidos (valores en segundos):
- MRC | no atómico | getters implementados manualmente: 2
- MRC | no atómico | getter sintetizado: 7
- MRC | atómico | getter sintetizado: 47
- ARC | no atómico | getter sintetizado: 38 (nota: ARC agrega ciclismo de recuento de referencia aquí)
- ARC | atómico | getter sintetizado: 47
Como probablemente haya adivinado, la actividad de conteo de referencia / ciclismo es un contribuyente significativo con los atómicos y bajo ARC. También vería mayores diferencias en los casos disputados.
Aunque presto mucha atención al rendimiento, sigo diciendo ¡ Semántica primero! . Mientras tanto, el rendimiento es de baja prioridad para muchos proyectos. Sin embargo, conocer los detalles de ejecución y los costos de las tecnologías que usa ciertamente no hace daño. Debe usar la tecnología adecuada para sus necesidades, propósitos y habilidades. Esperemos que esto le ahorre algunas horas de comparación y lo ayude a tomar una decisión mejor informada al diseñar sus programas.