面試時被問到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集合只需要獲取下一個地址就可以獲取到值,所以相比起來集合的遍歷速度更快。(如有錯誤,歡迎指正)