你好,歡迎來到IOS教程網

 Ios教程網 >> IOS編程開發 >> IOS開發基礎 >> ARC與MRC的性能對比

ARC與MRC的性能對比

編輯:IOS開發基礎

self-love-553243_640.jpg

MRC似乎已經是一個上古時代的話題了,不過我還是繞有興致的把它翻出來。因為,今天我被一個問題問住了:ARC與MRC的性能方面孰優劣。確實,之前沒有對比過。

先來做個測試吧。首先我們需要一個計時輔助函數,我選擇使用mach_absolute_time,計算時間差的函數如下:

double subtractTimes(uint64_t endTime, uint64_t startTime) {
    uint64_t difference = endTime - startTime;
    static double conversion = 0.0;
    if(conversion == 0.0) {
        mach_timebase_info_data_t info;
        kern_return_t err = mach_timebase_info(&info);                       //Convert the timebaseinto seconds
        if(err == 0)
            conversion = 1e-9 * (double) info.numer / (double) info.denom;
    }
    return conversion * (double)difference;
}

然後定義兩個測試類,一個是ARC環境下的,一個是MRC環境下的,分別如下:

// Test1.m
+ (void)test {
    uint64_t start,stop;
    start = mach_absolute_time();
    for (int i = 0; i < 1000000; i++) {
        NSArray *array = [[NSArray alloc] init];
    }
    stop = mach_absolute_time();
    double diff = subtractTimes(stop, start);
    NSLog(@"ARC total time in seconds = %f\n", diff);
}
// Test2.m
// 在target->Build Phases->Compile Sources中,添加編譯標識-fno-objc-arc
+ (void)test {
    uint64_t start,stop;
    start = mach_absolute_time();
    for (int i = 0; i < 1000000; i++) {
        NSArray *array = [[NSArray alloc] init];
        [array release];
    }
    stop = mach_absolute_time();
    double diff = subtractTimes(stop, start);
    NSLog(@"MRC total time in seconds = %f\n", diff);
}

多運行幾組測試,然後挑兩組吧來看看,數據如下:

// A組
ARC total time in seconds = 0.077761
MRC total time in seconds = 0.072469
// B組
ARC total time in seconds = 0.075722
MRC total time in seconds = 0.101671

從上面的數據可以看到,ARC與MRC各有快慢的情況。即使上升到統計學的角度,ARC也只是以輕微的優勢勝出。看來我的測試姿勢不對,並沒有證明哪一方占絕對的優勢。

嗯,那我們再來看看官方文檔是怎麼說的吧。在Transitioning to ARC Release Notes中有這麼一段話:

Is ARC slow?

It depends on what you’re measuring, but generally “no.” The compiler efficiently eliminates many extraneousretain/release calls and much effort has been invested in speeding up the Objective-C runtime in general. In particular, the common “return a retain/autoreleased object” pattern is much faster and does not actually put the object into the autorelease pool, when the caller of the method is ARC code.

One issue to be aware of is that the optimizer is not run in common debug configurations, so expect to see a lot more retain/release traffic at -O0 than at -Os.

再來看看別人的數據吧。Steffen Itterheim在Confirmed: Objective-C ARC is slow. Don’t use it! (sarcasm off)一文中給出了大量的測試數據。這篇文章是2013.3.20號發表的。Steffen Itterheim通過他的測試得出一個結論

ARC is generally faster, and ARC can indeed be slower

嗯,有些矛盾。不過在文章中,Steffen Itterheim指出大部分情況下,ARC的性能是更好的,這主要得益於一些底層的優化以及autorelease pool的優化,這個從官方文檔也能看到。但在一些情況下,ARC確實是更慢,ARC會發送一些額外的retain/release消息,如一些涉及到臨時變量的地方,看下面這段代碼:

// this is typical MRC code:
{
    id object = [array objectAtIndex:0];
    [object doSomething];
    [object doAnotherThing];
}
// this is what ARC does (and what is considered best practice under MRC):
{
    id object = [array objectAtIndex:0];
    [object retain]; // inserted by ARC
    [object doSomething];
    [object doAnotherThing];
    [object release]; // inserted by ARC
}

另外,在帶對象參數的方法中,也有類似的操作:

// this is typical MRC code:
-(void) someMethod:(id)object
{
    [object doSomething];
    [object doAnotherThing];
}
// this is what ARC does (and what is considered best practice under MRC):
-(void) someMethod:(id)object
{
    [object retain]; // inserted by ARC
    [object doSomething];
    [object doAnotherThing];
    [object release]; // inserted by ARC
}

這些些額外的retain/release操作也成了降低ARC環境下程序性能的罪魁禍首。但實際上,之所以添加這些額外的retain/release操作,是為了保證代碼運行的正確性。如果只是在單線程中執行這些操作,可能確實沒必要添加這些額外的操作。但一旦涉及以多線程的操作,問題就來了。如上面的方法中,object完全有可能在doSoming和doAnotherThing方法調用之間被釋放。為了避免這種情況的發生,便在方法開始處添加了[object retain],而在方法結束後,添加了[object release]操作。

如果想了解更多關於ARC與MRC性能的討論,可以閱讀一下Are there any concrete study of the performance impact of using ARC?與ARC vs. MRC Performance,在此就不過多的摘抄了。

實際上,即便是ARC的性能不如MRC,我們也應該去使用ARC,因此它給我們帶來的好處是不言而喻的。我們不再需要像使用MRC那樣,去過多的關注內存問題(雖然內存是必須關注的),而將更多的時間放在我們真正關心的事情上。如果真的對性能非常關切的話,可以考慮直接用C或C++。反正我是不會再回到MRC時代了。

參考

  • Are there any concrete study of the performance impact of using ARC?

  • ARC vs. MRC Performance

  • Confirmed: Objective-C ARC is slow. Don’t use it! (sarcasm off)

  • Transitioning to ARC Release Notes

  1. 上一頁:
  2. 下一頁:
蘋果刷機越獄教程| IOS教程問題解答| IOS技巧綜合| IOS7技巧| IOS8教程
Copyright © Ios教程網 All Rights Reserved