2013-02-08 4 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

+2

Я думаю, вы могли бы использовать GCD для создания многопоточной версии кода - код кажется хорошо подходящим для многопоточности. Это _might_ увеличивает производительность на некоторых платформах. –

+1

Предполагая, что они отсортированы и что вы нажимаете одну и ту же дату повторно, кеширование самой последней форматированной даты может сильно ускорить работу. – escrafford

ответ

4

Если честно, я думаю, что любые большие улучшения будут алгоритмическими изменениями, которые за пределами того, что мы можем здесь практически предложить (например, уменьшить количество циклов, которые вам нужно сделать, или устранить необходимость получения всех строк дат).

Есть несколько микро-оптимизаций, которые вы могли бы сделать, хотя я не ожидаю, что они сделают резкую разницу. В принципе, вы можете уменьшить количество отправляемых сообщений, используя кэширование IMP и методы перечисления NSArray вместо C for-loop, что должно дать небольшой импульс.

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.)

1

Для вашей петли довольно просто. То, что вы действительно ищете является оптимизацией самого метода stringFromDate ...

Проверить это

What are some possible optimizations for NSDateFormatter's stringFromDate?

Я не думаю, что есть что-то слишком много вы можете сделать. операция форматирования будет занимать некоторый процессор ... если вы не можете разработать собственный алгоритм, основанный на любых предположениях, которые вы можете сделать о своих входных значениях.

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

Смежные вопросы