Objective-C:一种判断时间戳在指定区间的方法

2020-06-22  本文已影响0人  Think_cy

背景

工作中在做某个业务需求的时候,某同事的实现,遇到了一个NSCalendar进行日期转换卡顿的问题。

最后分析发现是调用了NSCalendar的转换方法导致的,使用此方法是为了计算某个时间戳是否在某个区间内。

比如判断时间戳是美股盘前(夏令时:16:00~21:30)

使用NSCalendar实现

方法

代码

- (BOOL)timeStamp1:(uint32_t)timeStamp betweenFromHour:(NSInteger)fromHour fromMinute:(NSInteger)fromMinute toHour:(NSInteger)toHour toMinute:(NSInteger)toMinute {
    NSDate *date = [[NSDate alloc] initWithTimeIntervalSince1970:timeStamp];
    NSCalendar *calendar = [NSCalendar currentCalendar]; // 注意:这里每次创建都会耗性能,考虑使用技能变量
    unsigned unitFlags = NSCalendarUnitHour | NSCalendarUnitMinute;
    
    // 计算dateComponents,这里也是比较耗时的
    NSDateComponents *dateComponents = [calendar components:unitFlags fromDate:date];
    
    BOOL fromResult = (dateComponents.hour > fromHour) || (dateComponents.hour == fromHour && dateComponents.minute >= fromMinute);
    BOOL toResult = (dateComponents.hour < toHour) || (dateComponents.hour == toHour && dateComponents.minute <= toMinute);
    
    return toResult && fromResult;
}

效率

indicator_07.png

每个执行3次求平均值

执行次数 耗时(us)
1,000 1,496
10,000 11,451
100,000 82,826
1,000,000 826,596
10,000,000 8,341,402

使用时间戳特点

方法

目的是计算时间戳是否在某一天的某个区间,所以可以采用对时间戳取余数的方法进行对比。

我们知道一天的时间是24 * 60 * 60,则对应的时间戳对其取余则是在这一天的某一时刻。

当天的时间00:00:00~23:59:59对应的时间戳为0~86399,则余数也应该在这个范围。

所以我们可以利用这个区间去判断指定时间戳是否在这个区间。如下图所示:

indicator_05.png

代码

#define DAY_UNIT (86400)
#define DAY_GMT0_08_00 (28800)  // GMT8 16:00
#define DAY_GMT0_13_30 (48600)  // GMT8 21:30

- (BOOL)timeStamp:(uint32_t)timeStamp betweenFromHour:(NSInteger)fromHour fromMinute:(NSInteger)fromMinute toHour:(NSInteger)toHour toMinute:(NSInteger)toMinute {
    int reminder = timeStamp % DAY_UNIT;
    return reminder >= DAY_GMT0_08_00 && reminder <= DAY_GMT0_13_30;
}

效率

执行次数 耗时(us)
1,000 12
10,000 100
100,000 882
1,000,000 6,822
10,000,000 71,616

结论

对比

indicator_06.png

可看出来,对于执行次数优化非常明显,基本都是99%以上。

分析

根据优化效果,以后如果有关于日历方面的计算,建议思考一下是否需要考虑性能问题。

上一篇下一篇

猜你喜欢

热点阅读