iOS 之 測試效率

面試時被問到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);

測試結果如下:


可見NSMutableSet是要快於NSMutableArray的。

理由:

NSMutableArray其實就是一種特殊的集合,其內部有序,所以每次遍歷的時候都要獲取其下標計算其地址,然後再獲取值;而NSMutableSet集合只需要獲取下一個地址就可以獲取到值,所以相比起來集合的遍歷速度更快。(如有錯誤,歡迎指正)



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章