iOS:方法在设备和模拟器上测试慢25倍

时间:2012-02-29 14:16:30

标签: ios performance ios-simulator

与模拟器相比,我有一种在设备(iPhone3G)中运行速度非常慢的方法。

虽然模拟器可以在1秒内处理大约100次方法,但设备只能在一秒钟内运行4次。

什么能让它变得如此懒散?

CODE: 注意:该方法从两个日期(事件的开始日期和结束日期)计算人类友好字符串。

-(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 个答案:

答案 0 :(得分:17)

iOS设备的功能远远低于运行模拟器的计算机。 iOS模拟器不会模拟ARM进程,因此它会全速运行。

此外,此特定方法速度太慢的原因是由于NSDateFormatterNSCalendar对象的创建。这些是相当昂贵的创建,如果你想多次使用它们应该缓存在实例变量/属性中。

答案 1 :(得分:13)

你应该缓存这个变量,它很慢。调用此方法一次。

NSCalendar *calendar = [NSCalendar currentCalendar];

答案 2 :(得分:1)

为INTEL处理器编译模拟器是正常的,当您在模拟器上进行测试时,您的应用程序正在为INTEL构建,并且正在使用您所有计算机CPU的电源。所以它的速度更快。

您可以使用仪器查看哪个部分正在减速​​执行。

答案 3 :(得分:0)

避免在循环中使用NSDateFormatter。

我通过使用stringWithFormat将date转换为字符串然后使用componentsSeparatedByString来破坏组件来修复它。

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

通过这样做,我能够在几秒钟内在不到一秒的时间内执行我的循环。

希望这会有所帮助。

答案 4 :(得分:0)

实例化NSDateFormatter和NSCalendar不是非常重要的操作。在我的测试中,在iPhone 4s上创建NSDateFormatter最多可能需要250毫秒。避免重新创建这些对象,如果可能的话,将它们保留为类ivars或静态对象。尽可能重复使用。