2013-02-08 119 views
2

我在仪器中运行时间分析器。我尽可能简化了代码,将所有事情都归结为一个确切的问题。循环内有一行代码checkInString = [_ formatter stringFromDate:[checkInArrayCopy objectAtIndex:i]];正在占用90%的处理时间。关于如何优化此代码的任何想法?优化此循环

NSDateFormatter *format = [[NSDateFormatter alloc]init]; 
[format setTimeZone:[NSTimeZone timeZoneWithAbbreviation:@"GMT"]]; 
[format setDateFormat:@"MM/dd/YYYY"]; 
NSString *checkInString; 
for (int x=0; x<100; x++) { 
    for (int i=0; i<checkInArray.count; i++) { //CheckInArray is a NSMutableArray of NSDates, with about 100 objects inside 
     checkInString =[_formatter stringFromDate:[checkInArray objectAtIndex:i]]; //**90% of processing time 
    } 
} 
+0

虽然您可能无法优化日期格式化程序(如果有的话),但是如果使用'NSSet'中的不同日期集合来减少循环次数,您可能会稍微减轻一些循环次数,具体取决于是否不是你正在使用分钟/秒/毫秒。所以,如果你能够将这些日期压缩到一半,那么你就需要更少的时间格式化。 – Jeremy 2013-02-08 18:32:35

+2

我想你可能可以使用GCD创建一个多线程版本的代码 - 代码似乎非常适合多线程。这可以提高某些平台的性能。 – 2013-02-08 19:19:00

+1

假设这些内容已排序,并且您重复使用同一日期,缓存最近格式化的日期可能会加速很多事情。 – escrafford 2013-02-08 19:24:13

回答

4

说实话,我认为任何重大的改进都会是算法上的改变,超出了我们在这里实际建议的范围(例如,减少您需要执行的循环量,或者消除获取所有日期字符串的需要)。

你可以做一些微观优化,但我不认为它们会有很大的不同。基本上,你可以通过使用IMP缓存和NSArray的枚举方法而不是C for for循环来减少你的消息发送次数,这应该给予小的提升。

NSDateFormatter *format = [[NSDateFormatter alloc]init]; 
[format setTimeZone:[NSTimeZone timeZoneWithAbbreviation:@"GMT"]]; 
[format setDateFormat:@"MM/dd/YYYY"]; 
__block NSString *checkInString; 
id (*stringFromDateIMP)(id, SEL, id) = [_formatter methodForSelector:@selector(stringFromDate:)]; 
for (int x=0; x<100; x++) { 
    [checkInArray enumerateObjectsUsingBlock:^(NSDate *date, NSUInteger i, BOOL *stop) { //CheckInArray is a NSMutableArray of NSDates, with about 100 objects inside 
     checkInString = stringFromDateIMP(_formatter, @selector(stringFromDate:), date); 
    }]; 
} 

(写于浏览器,因此警告compilor

2

具有明显的免责声明,有可能是一些我已经完全错过,当前的代码做同样的日期转换100次。

如果这是正确的,那么只需进行一次转换就可以获得很多收益。下面的代码演示的原则,但请注意,这是未经测试,所以用你的常识,阅读时:

NSDateFormatter *format = [[NSDateFormatter alloc]init]; 
[format setTimeZone:[NSTimeZone timeZoneWithAbbreviation:@"GMT"]]; 
[format setDateFormat:@"MM/dd/YYYY"]; 

NSMutableArray *dates = [NSMutableArray array]; 
for (int i=0; i<checkInArray.count; i++) { //CheckInArray is a NSMutableArray of NSDates, with about 100 objects inside 
    NSString *cis =[format stringFromDate:[checkInArray objectAtIndex:i]] 
    [dates addObject: cis]; 
} 

NSString *checkInString; 
for (int x=0; x<100; x++) { 
    for (int i=0; i<checkInArray.count; i++) { 
     checkInString = [dates objectAtIndex:i]; 
    } 
} 

的代码维护您的objectAtIndex:使用,您可能需要使用一个foreach或块做循环,但这是一个细节。

+0

由于原始代码中的显而易见的遗漏(两个循环实际上都没有象在OP中写的那样是无意义的),这很难说,但是如果外部循环的内容实际上允许它,这可能是一个好建议,所以+1 。 – Chuck 2013-02-08 20:27:00