iOS: метод тестирования в 25 раз медленнее на устройстве по сравнению с симулятором - PullRequest
8 голосов
/ 29 февраля 2012

У меня есть метод, который запускает невероятно медленное тестирование в устройстве (iPhone3G) по сравнению с симулятором.

Хотя симулятор может обрабатывать около 100 выполнений метода за 1 секунду, устройство может запускаться только 4 раза, считая метод за секунду.

Что может сделать это бездельником?

КОД: Примечание. Метод вычисляет удобную для человека строку по двум датам (дата начала и дата окончания события).

-(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");
}

Ответы [ 5 ]

17 голосов
/ 29 февраля 2012

iOS-устройства значительно менее мощны, чем компьютер, на котором вы запускаете симулятор.Симулятор iOS не эмулирует процессор ARM, поэтому он запускает его на полной скорости.

Кроме того, причина, по которой этот конкретный метод является настолько медленным, заключается в создании NSDateFormatter и NSCalendarобъекты.Их создание довольно дорого, и их следует кэшировать в переменной / свойстве экземпляра, если вы хотите использовать их несколько раз.

13 голосов
/ 29 февраля 2012

Вы должны кэшировать эту переменную, она очень медленная. Вызовите этот метод один раз.

NSCalendar *calendar = [NSCalendar currentCalendar];
1 голос
/ 29 февраля 2012

Это нормально, что симулятор скомпилирован для процессоров INTEL, когда вы тестируете на симуляторе, ваше приложение собирается для INTEL и использует всю мощность процессора вашего компьютера. Так что это намного быстрее.

Вы можете использовать инструмент, чтобы увидеть, какая часть замедляет выполнение.

0 голосов
/ 04 июля 2015

Создание экземпляров NSDateFormatter и NSCalendar не является нетривиальной операцией.На моем тестировании создание NSDateFormatter может занять до 250 мс на iPhone 4s.Избегайте воссоздания этих объектов, если возможно, сохраняйте их как классы ivars или статические объекты.Повторно используйте, когда сможете.

0 голосов
/ 20 октября 2014

Избегайте использования NSDateFormatter в цикле.

Я исправил это, преобразовав дату в строку, используя stringWithFormat, а затем разбив компоненты с помощью componentSeparatedByString.

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

Сделав это, я смогвыполнить мой цикл менее чем за секунду из пары секунд.

Надеюсь, это поможет.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...