NSDateComponents Time Profile

最后都变了- 提交于 2020-01-15 07:40:29

问题


My problem is to do with the Time Profile of NSDateComponents operations given in the code snippet below.

  • I have a method that iterates over a large array of NSDate objects
  • Part of the method requires that I discard the Hour, Minute and seconds of each date.
  • To do this I have 3 steps:

    1. I create an NSDateComponents object from my original date.
    2. I set the H:M:S elements to 0
    3. I get my new date object that has H:M:S set to 0 as needed

The Issue:

Steps 1 & 3 above are taking a huge percentage of my overall method execution time, 22.4% and 56.8% respectively.

I'm looking for suggestions as to how I might optimize this part of my code or alternative ways of zeroing the H:M:S that might perform better.

NSDate* date = [[NSDate alloc] init];
// Next line takes 22.4% of the overall method execution time
NSDateComponents* components =  [calendar components:(NSYearCalendarUnit | NSMonthCalendarUnit 
                                | NSDayCalendarUnit | NSHourCalendarUnit  
                                | NSSecondCalendarUnit) fromDate:date]; 

[components setHour:0];
[components setMinute:0];
[components setSecond:0];

// Next line takes 56.8% of the overall method execution time
date = [calendar dateFromComponents:components];

回答1:


Update

Clocks:

Time 1: ≈ 0.000139 - Option 1 - Original

Time 2: ≈ 0.000108 - Option 2

Time 3: ≈ 0.000013 - Option 3

Time 4: ≈ 0.000004 - Option 4

Option 1 - Original

NSDate* originDate = [[NSDate alloc] init];
NSDate* date = [[NSDate alloc] init];
NSCalendar *calendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
NSDateComponents* components =  [calendar components:(NSYearCalendarUnit | NSMonthCalendarUnit
                                                      | NSDayCalendarUnit | NSHourCalendarUnit
                                                      | NSSecondCalendarUnit) fromDate:date];

[components setHour:0];
[components setMinute:0];
[components setSecond:0];
date = [calendar dateFromComponents:components];
NSLog(@"Time 1: %f", -[originDate timeIntervalSinceNow]);

Option 2

You don't need

[components setHour:0];
[components setMinute:0];
[components setSecond:0];

Just don't even add these as options to date components

NSDate* originDate2 = [[NSDate alloc] init];
NSDate* date2 = [[NSDate alloc] init];
NSCalendar *calendar2 = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];

NSDateComponents* components2 =  [calendar2 components:(NSYearCalendarUnit | NSMonthCalendarUnit
                                                        | NSDayCalendarUnit
                                                        ) fromDate:date2];
date2 = [calendar2 dateFromComponents:components2];
NSLog(@"Time 2: %f", -[originDate2 timeIntervalSinceNow]);

Sources: Similar Question + David's Comment

Option 3

Basically, I found that if I run the method with an already created NSCalendar, I get 85% to 90% faster speed consistently.

Declare calendarProperty and initialize it before you run the method

NSDate* originDate3 = [[NSDate alloc] init];
NSDate* date3 = [[NSDate alloc] init];
NSDateComponents* components3 =  [calendarProperty components:(NSYearCalendarUnit | NSMonthCalendarUnit
                                                               | NSDayCalendarUnit
                                                               ) fromDate:date3];
date3 = [calendarProperty dateFromComponents:components3];
NSLog(@"Time 3: %f", -[originDate3 timeIntervalSinceNow]);

Option 4

* based on @HotLicks's comment *

Avoid all those annoying dateComponents all together - about 95% faster

I'm not sure about how consistent Option 4 is in practice, but it's clocking in the fastest and it has been reliable for me so far.

NSDate* originDate4 = [[NSDate alloc] init];
NSDate* date4 = [[NSDate alloc] init];
float date4Interval = [date4 timeIntervalSince1970];
int totalDays = date4Interval / (60 * 60 * 24);
date4 = [NSDate dateWithTimeIntervalSince1970:totalDays * 60 * 60 * 24];
NSLog(@"Time 4: %f", -[originDate4 timeIntervalSinceNow]);


来源:https://stackoverflow.com/questions/22206358/nsdatecomponents-time-profile

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!