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