zoukankan      html  css  js  c++  java
  • ARC与MRC的性能对比

    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
    ", 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
    ", 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时代了。

  • 相关阅读:
    深入理解多态..............................
    走过路过 不要错过..
    进军C#..
    员工打卡....
    MySQL
    MySQL
    MySQL
    MySQL
    MySQL
    MySQL
  • 原文地址:https://www.cnblogs.com/zhaohanjun/p/4747436.html
Copyright © 2011-2022 走看看