面试时被问到NSArray和NSSet 哪个遍历更快?
虽然知道理论,但是毕竟没有验证过,那么今天就来用代码验证一下。
使用CFAbsoluteTimeGetCurrent 来测试运行效率,CFAbsoluteTimeGetCurrent 和NSDate不同,其基于内建时钟,形成一个绝对时间段,能够更精确更原子化的测试,,并且不会因外界的时间变化而变化(例如时区变化,秒突变等)
看第一个例子:测试NSMutableArray arrayWithCapacity:和 NSMutableArray array谁的遍历更快
static size_t const count = 1000;
static size_t const iterations = 10000;
id object = @"[]";
CFTimeInterval startTime1 = CACurrentMediaTime();
{
for (size_t i = 0; i < iterations; i++) {
@autoreleasepool {
NSMutableArray *mutableArray = [NSMutableArray arrayWithCapacity:count];
for (size_t j = 0; j < count; j++) {
[mutableArray addObject:object];
}
}
}
}
CFTimeInterval endTime1 = CACurrentMediaTime();
NSLog(@"Total Runtime: %g s", endTime1 - startTime1);
CFTimeInterval startTime = CACurrentMediaTime();
{
for (size_t i = 0; i < iterations; i++) {
@autoreleasepool {
NSMutableArray *mutableArray = [NSMutableArray array];
for (size_t j = 0; j < count; j++) {
[mutableArray addObject:object];
}
}
}
}
CFTimeInterval endTime = CACurrentMediaTime();
NSLog(@"Total Runtime: %g s", endTime - startTime);
打印出的结果是:
可见NSMutableArray arrayWithCapacity:比 NSMutableArray array更快一些;
下面换另一种方法测试,dispatch_benchmark,这种方法相比于之前的方法更加精确,可读性也更高。
由于dispatch_benchmark是GCD的一部分,且并没有公开声明,所以需要自己先声明,还是刚才的例子:
extern uint64_t dispatch_benchmark(size_t count, void (^block)(void));
uint64_t t_0 = dispatch_benchmark(iterations, ^{
@autoreleasepool {
NSMutableArray *mutableArray = [NSMutableArray array];
for (size_t i = 0; i < count; i++) {
[mutableArray addObject:object];
}
}
});
NSLog(@"[[NSMutableArray array] addObject:] Avg. Runtime: %llu ns", t_0);
uint64_t t_1 = dispatch_benchmark(iterations, ^{
@autoreleasepool {
NSMutableArray *mutableArray = [NSMutableArray arrayWithCapacity:count];
for (size_t i = 0; i < count; i++) {
[mutableArray addObject:object];
}
}
});
NSLog(@"[[NSMutableArray arrayWithCapacity] addObject:] Avg. Runtime: %llu ns", t_1);
打印结果如下:
下面用dispatch_benchmark 测试NSMutableArray 和NSMutableSet 的遍历速度谁更快:
extern uint64_t dispatch_benchmark(size_t count, void (^block)(void));
static size_t const count = 1000;
static size_t const iterations = 10000;
//测试NSMutableArray 和NSMutableSet 的遍历速度谁更快
uint64_t t_0 = dispatch_benchmark(iterations, ^{
@autoreleasepool {
NSMutableArray *mutableArray = [NSMutableArray array];
for (size_t i = 0; i < count; i++) {
[mutableArray addObject:object];
}
}
});
NSLog(@"[[NSMutableArray array] addObject:] Avg. Runtime: %llu ns", t_0);
uint64_t t_1 = dispatch_benchmark(iterations, ^{
@autoreleasepool {
NSMutableSet *mutableArray = [NSMutableSet set];
for (size_t i = 0; i < count; i++) {
[mutableArray addObject:object];
}
}
});
NSLog(@"[[NSMutableSet set] addObject:] Avg. Runtime: %llu ns", t_1);
测试结果如下:
理由:
NSMutableArray其实就是一种特殊的集合,其内部有序,所以每次遍历的时候都要获取其下标计算其地址,然后再获取值;而NSMutableSet集合只需要获取下一个地址就可以获取到值,所以相比起来集合的遍历速度更快。(如有错误,欢迎指正)