2012-02-29 19 views
8

Tengo un método que ejecuta pruebas increíblemente lentas en el dispositivo (iPhone3G) en comparación con el simulador.iOS: Método de prueba 25 veces más lento en el dispositivo frente al simulador

Mientras que el simulador puede manejar alrededor de 100 ejecuciones del método en 1 segundo, el dispositivo solo puede ejecutar 4 veces el método pensado en un segundo.

¿Qué puede hacer que sea tan sloooow?

CÓDIGO: Nota: El método calcula una cadena amigable para el hombre a partir de dos fechas (fecha de inicio y fecha de finalización de un evento).

-(void)calculateDiaDeInicioYFinTexto 
{ 
    NSLog(@"inicio"); 
    NSAutoreleasePool *localPool = [[NSAutoreleasePool alloc] init]; 

    NSMutableString *auxString = [NSMutableString string]; 

    NSLocale *currLocale = [NSLocale currentLocale]; 

    NSString *stringFormatDay = [NSDateFormatter dateFormatFromTemplate:@"d" 
                   options:0 
                   locale:currLocale]; 
    NSString *stringFormatDayMonth = [NSDateFormatter dateFormatFromTemplate:@"dMMMM" 
                    options:0 
                     locale:currLocale]; 
    NSString *stringFormatDayMonthYear = [NSDateFormatter dateFormatFromTemplate:@"dMMMMYYYY" 
                     options:0 
                      locale:currLocale]; 

    NSDateFormatter *formatterDay = [[NSDateFormatter alloc] init]; 
    [formatterDay setDateFormat:stringFormatDay]; 
    [formatterDay setLocale:currLocale]; 

    NSDateFormatter *formatterDayMonth = [[NSDateFormatter alloc] init]; 
    [formatterDayMonth setDateFormat:stringFormatDayMonth]; 
    [formatterDayMonth setLocale:currLocale]; 

    NSDateFormatter *formatterDayMonthYear = [[NSDateFormatter alloc] init]; 
    [formatterDayMonthYear setDateFormat:stringFormatDayMonthYear]; 
    [formatterDayMonthYear setLocale:currLocale]; 


    NSCalendar *calendar = [NSCalendar currentCalendar]; 

    NSDateComponents *dateComponentsNow = [calendar components:(NSYearCalendarUnit | 
                   NSMonthCalendarUnit | 
                   NSDayCalendarUnit) 
                 fromDate:[NSDate date]]; 
    NSDateComponents *dateComponentsInicio = [calendar components:(NSYearCalendarUnit | 
                    NSMonthCalendarUnit | 
                    NSDayCalendarUnit) 
                 fromDate:self.diaDeInicio]; 
    NSDate *diaDeInicioTimeless = [calendar dateFromComponents:dateComponentsInicio]; 

    NSDateComponents *dateComponentsFin = [calendar components:(NSYearCalendarUnit | 
                   NSMonthCalendarUnit | 
                   NSDayCalendarUnit) 
                 fromDate:self.diaDeFin]; 
    NSDate *diaDeFinTimeless = [calendar dateFromComponents:dateComponentsFin]; 


    if ([diaDeInicioTimeless isEqualToDate:diaDeFinTimeless]) { 
     // dates are the same 
     if (dateComponentsInicio.year == dateComponentsNow.year) { 
      // date is in the current year 
      [auxString appendFormat:@"%@", [formatterDayMonth stringFromDate:self.diaDeInicio]]; 
     } else { 
      // date is in another year 
      [auxString appendFormat:@"%@", [formatterDayMonthYear stringFromDate:self.diaDeInicio]]; 
     } 
    } else { 
     // dates are different 
     if (dateComponentsInicio.year == dateComponentsFin.year) { 
      // years are the same 
      if (dateComponentsInicio.month == dateComponentsFin.month) { 
       // Months are the same 
       if (dateComponentsInicio.year == dateComponentsNow.year) { 
        // date is in the current year 
        [auxString appendFormat:@"%@ - %@", 
        [formatterDay stringFromDate:self.diaDeInicio], 
        [formatterDayMonth stringFromDate:self.diaDeFin]];      
       } else { 
        // date is in another year 
        [auxString appendFormat:@"%@ - %@", 
        [formatterDay stringFromDate:self.diaDeInicio], 
        [formatterDayMonthYear stringFromDate:self.diaDeFin]];           
       } 
      } else { 
       // Months are different 
       if (dateComponentsInicio.year == dateComponentsNow.year) { 
        // date is in the current year 
        [auxString appendFormat:@"%@ - %@", 
        [formatterDayMonth stringFromDate:self.diaDeInicio], 
        [formatterDayMonth stringFromDate:self.diaDeFin]];      
       } else { 
        // date is in another year 
        [auxString appendFormat:@"%@ - %@", 
        [formatterDayMonth stringFromDate:self.diaDeInicio], 
        [formatterDayMonthYear stringFromDate:self.diaDeFin]];      
       } 
      } 
     } else { 
      // Years are different 
      [auxString appendFormat:@"%@ - %@", 
      [formatterDayMonthYear stringFromDate:self.diaDeInicio], 
      [formatterDayMonthYear stringFromDate:self.diaDeFin]];    
     } 
    } 
    self.diaDeInicioYFinTexto = auxString; 
    [formatterDay release]; 
    [formatterDayMonth release]; 
    [formatterDayMonthYear release]; 
    [localPool release]; 

    NSLog(@"Fin"); 
} 
+1

El dispositivo es MUCHO más lento que el simulador ... por lo tanto, el simulador de nombres y no el emulador. ¿Es un problema de rendimiento notable? ¿Has ejecutado Time Profiler (con el dispositivo)? –

Respuesta

16

Los dispositivos iOS son considerablemente menos potentes que la computadora con la que está ejecutando el simulador. El simulador de iOS no emula el proccessor ARM y lo ejecuta a toda velocidad.

Además, la razón por la que este método en particular es tan lento se debe a la creación de los objetos NSDateFormatter y NSCalendar. Esos son bastante caros de crear y deben almacenarse en caché en una variable/propiedad de instancia si desea usarlos varias veces.

+0

Guarde en caché eso y obtengo 50 ejecuciones del método en un segundo (12 veces más rápido), y solo la mitad del tiempo en comparación con el simulador. Tendré que verificar esto en mis bucles a partir de ahora. –

1

Es normal que el simulador está compilado para procesadores Intel, cuando se está probando en el simulador de su aplicación se está construyendo para Intel y está utilizando toda la potencia de la CPU del ordenador. Entonces es mucho más rápido.

Puede usar el instrumento para ver qué parte está ralentizando la ejecución.

13

Debe almacenar en caché esta variable, es muy lenta. Llamar a este método una vez.

NSCalendar *calendar = [NSCalendar currentCalendar]; 
+0

Si lo siguiente es verdadero: http://mikeabdullah.net/NSCalendar_currentCalendar.html, no es necesario que guarde '' NSCalendar currentCalendar] por más tiempo, comenzando con ios 7 en adelante. –

0

Evite el uso de NSDateFormatter en el ciclo.

Lo arreglé convirtiendo la fecha en cadena usando stringWithFormat y luego descomponiendo los componentes usando componentsSeparatedByString.

NSString *stringDate = [NSString stringWithFormat:@"%@",mydate]; 
NSArray *stringArray = [stringDate componentsSeparatedByString: @" "]; 
NSArray *timeArray = [stringArray[1] componentsSeparatedByString: @":"]; 

Al hacer esto, pude ejecutar mi ciclo en menos de un segundo desde un par de segundos.

Espero que esto ayude.

0

Creación de instancias NSDateFormatter y NSCalendar no son operaciones no triviales. Crear un NSDateFormatter puede tomar hasta 250ms en un iPhone 4s, en mis pruebas. Evite volver a crear estos objetos, manteniéndolos como ivars de clase u objetos estáticos si es posible. Reutilizar siempre que puedas.

Cuestiones relacionadas