NSEnumerator rendimiento vs bucle for en el Cacao
-
09-06-2019 - |
Pregunta
Yo sé que si usted tiene un bucle que se modifica el recuento de los elementos en el circuito, utilizando el NSEnumerator en un conjunto es la mejor manera de asegurarse de que su código de golpes, sin embargo, me gustaría conocer el rendimiento de los equilibrios entre la NSEnumerator clase y sólo una vieja escuela de bucle
Solución
El uso de las nuevas for (... in ...)
la sintaxis de Objective-C 2.0 es generalmente la manera más rápida para iterar sobre una colección, porque se puede mantener un buffer en la pila y obtener lotes de elementos en él.
El uso de NSEnumerator
generalmente es la más lenta de todas, porque a menudo copias de la colección se itera;para las colecciones inmutables esto puede ser barato (equivalente a -retain
) pero para colecciones mutables puede causar una inmutable copia para ser creado.
Haciendo su propia repetición — por ejemplo, el uso de -[NSArray objectAtIndex:]
— generalmente caen en algún lugar entre porque aunque no tenga el potencial de carga en la copia, usted también no será la obtención de lotes de objetos de la subyacente de la colección.
(PS - Esta pregunta debe ser etiquetada como Objective-C, no C, ya que NSEnumerator
es un Cacao de la clase y el nuevo for (... in ...)
la sintaxis es específico para Objective-C.)
Otros consejos
Después de la ejecución de la prueba varias veces, el resultado es casi el mismo.Cada medida de bloque se ejecuta 10 veces de forma consecutiva.
El resultado en mi caso desde la más rápida a la más lenta:
- Para..en (testPerformanceExample3) (0.006 seg)
- Mientras (testPerformanceExample4) (0.026 seg)
- For(;;) (testPerformanceExample1) (0.027 seg.)
- La enumeración de bloque (testPerformanceExample2) (0.067 s)
El for y while loop es casi el mismo.
El tmp
es un NSArray
que contiene 1 millón de objetos de 0 a 999999.
- (NSArray *)createArray
{
self.tmpArray = [NSMutableArray array];
for (int i = 0; i < 1000000; i++)
{
[self.tmpArray addObject:@(i)];
}
return self.tmpArray;
}
El código completo:
ViewController.h
#import <UIKit/UIKit.h>
@interface ViewController : UIViewController
@property (strong, nonatomic) NSMutableArray *tmpArray;
- (NSArray *)createArray;
@end
ViewController.m
#import "ViewController.h"
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
[self createArray];
}
- (NSArray *)createArray
{
self.tmpArray = [NSMutableArray array];
for (int i = 0; i < 1000000; i++)
{
[self.tmpArray addObject:@(i)];
}
return self.tmpArray;
}
@end
MyTestfile.m
#import <UIKit/UIKit.h>
#import <XCTest/XCTest.h>
#import "ViewController.h"
@interface TestCaseXcodeTests : XCTestCase
{
ViewController *vc;
NSArray *tmp;
}
@end
@implementation TestCaseXcodeTests
- (void)setUp {
[super setUp];
vc = [[ViewController alloc] init];
tmp = vc.createArray;
}
- (void)testPerformanceExample1
{
[self measureBlock:^{
for (int i = 0; i < [tmp count]; i++)
{
[tmp objectAtIndex:i];
}
}];
}
- (void)testPerformanceExample2
{
[self measureBlock:^{
[tmp enumerateObjectsUsingBlock:^(NSNumber *obj, NSUInteger idx, BOOL *stop) {
obj;
}];
}];
}
- (void)testPerformanceExample3
{
[self measureBlock:^{
for (NSNumber *num in tmp)
{
num;
}
}];
}
- (void)testPerformanceExample4
{
[self measureBlock:^{
int i = 0;
while (i < [tmp count])
{
[tmp objectAtIndex:i];
i++;
}
}];
}
@end
Para más información visite: Las manzanas "Acerca de las Pruebas con Xcode"
Son muy similares.Con Objective-C 2.0 la mayoría de las enumeraciones ahora defecto NSFastEnumeration
que crea un búfer de las direcciones a cada objeto de la colección que se puede entregar.El paso que puede ahorrar con el clásico bucle for es no tener que llamar objectAtIndex:i
cada vez que en el interior del bucle.Los componentes internos de la colección, al enumerar implementar rápida enumeración con llamadas objectAtIndex:i method
.
El buffer es parte de la razón por la que usted no puede mutar una colección como la de enumerar, la dirección de los objetos que va a cambiar y el buffer que fue construido ya no coinciden.
Como un bono, el formato en el 2.0 se ve tan bonito como el clásico bucle for:
for ( Type newVariable in expression ) {
stmts
}
Lea la siguiente documentación para profundizar más:NSFastEnumeration Protocolo De Referencia