iOS 功能拦截 2.0(限制对某些接口的频繁调用)--基准测试
最编程
2024-05-08 07:19:32
...
Xcode 自带的单元测试框架可以很方便的测量一个方法的执行效率,measureBlock
里的代码会被执行十次,测试结束后会得到每次执行耗时,以及平均数和方差。
- (void)testPerformanceExample {
// This is an example of a performance test case.
NSDate *date = [NSDate date];
[self measureBlock:^{
// Put the code you want to measure the time of here.
for (int i = 0; i < 1000; i ++) {
@autoreleasepool {
[self.sstub foo:date];
}
}
}];
}
性能损耗大多发生在消息转发流程上的处理,为了能够校准基线,需要让每次消息发送都执行。MessageThrottle 1.2.0 刚刚支持了让某些条件下消息永远执行的特性:
- (void)setUp {
[super setUp];
// Put setup code here. This method is called before the invocation of each test method in the class.
self.sstub = [SuperStub new];
MTRule *rule = [self.sstub mt_limitSelector:@selector(foo:) oncePerDuration:0.01 usingMode:MTPerformModeDebounce];
rule.alwaysInvokeBlock = ^(MTRule *rule, NSDate *date) {
return YES; // 让消息永远都执行
};
}
通过调整 foo:
方法的耗时来得到调用不同耗时函数的测试结果。
- (void)foo:(NSDate *)arg {
[NSThread sleepForTimeInterval:0.0001];
}
最终得到一组数据,测试机器为 iPhone 8 plus。
执行模式\被调用方法耗时 | 0.0001 | 0.001 |
---|---|---|
不使用 MT | 0.118(baseline) | 1.17(baseline) |
MT 立即执行 | 0.135(14.4%worse) | 1.33(13.8%worse) |
MT debounce 0.01s | 0.0281(76.2%better) | 0.0279(97.6%better) |
- 测试的基准数据为不使用 MessageThottle,直接调用方法。
- 使用 MessageThottle 后,消息转发流程会带来多余的耗时会导致性能下降,而且被调用方法耗时越少,性能下降得越明显(比较两列数据)。
- 如果加了消息限频,会忽略掉一部分调用,这样当出现大量频繁调用时,方法真正执行的次数很少,性能反而大大提升了(第三行数据)