iOS面试库iOS开发之常用技术点快速入门iOS

iOS中各种锁的性能对比

2016-11-27  本文已影响757人  o0阿拉斯加的狗0o

自旋锁 与 互斥锁

  • 自旋锁 (spin lock): 如果一个线程需要获取自旋锁,该锁已经被其他线程占用,该线程不会被挂起,而是不断消耗CPU时间,一直试图获取自旋锁。

使用场景:

  • 多核处理器:如果预计线程等待锁的时间比较短,短到比线程两次切换上下文的时间还要少的情况下,自旋锁是更好的选择。如果时间比较长,则互斥锁是比较好的选择。

如果加锁的代码经常被调用,但是竞争发生的比较少时,应该优先考虑使用自旋锁,毕竟互斥锁的切换上下文的开销比较大。

性能对比

iOS中的锁包括:

  • @synchronized

做的测试是对每种锁进行100万次的加锁解锁操作,对比时间,使用的iPhone6iOS10.1.1的设备,测试结果如下:

各种锁的时间性能对比

从对比可以看出,性能最优的是OSSpinLock ,最差的是@synchronized,下面是我制作的各种锁的性能对比,不同的系统和设备的数值可能会有差异:

iOS中各种锁的性能对比

<h3 align = "center">测试代码</h3>

<a name="fenced-code-block">@synchronized()</a>

    CFTimeInterval timeBefore;
    CFTimeInterval timeCurrent;
    NSUInteger i;
    NSUInteger count = 1000*10000;//执行一千万次

    //@synchronized
    id obj = [[NSObject alloc]init];;
    timeBefore = CFAbsoluteTimeGetCurrent();
    for(i=0; i<count; i++){
        @synchronized(obj){
        }
    }
    timeCurrent = CFAbsoluteTimeGetCurrent();
    printf("@synchronized  : %f\n", timeCurrent-timeBefore);
<a name="fenced-code-block">NSLock</a>
    NSLock *lock = [[NSLock alloc]init];
    timeBefore = CFAbsoluteTimeGetCurrent();
    for(i=0; i<count; i++){
        [lock lock];
        [lock unlock];
    }
    timeCurrent = CFAbsoluteTimeGetCurrent();
    printf("NSLock  : %f\n", timeCurrent-timeBefore);
<a name="fenced-code-block">NSCondition</a>
    NSCondition *condition = [[NSCondition alloc]init];
    timeBefore = CFAbsoluteTimeGetCurrent();
    for(i=0; i<count; i++){
        [condition lock];
        [condition unlock];
    }
    timeCurrent = CFAbsoluteTimeGetCurrent();
    printf("NSCondition  : %f\n", timeCurrent-timeBefore);
<a name="fenced-code-block">NSConditionLock</a>
    NSConditionLock *conditionLock = [[NSConditionLock alloc]init];
    timeBefore = CFAbsoluteTimeGetCurrent();
    for(i=0; i<count; i++){
        [conditionLock lock];
        [conditionLock unlock];
    }
    timeCurrent = CFAbsoluteTimeGetCurrent();
    printf("NSConditionLock  : %f\n", timeCurrent-timeBefore);
<a name="fenced-code-block">NSRecursiveLock</a>
    NSRecursiveLock *recursiveLock = [[NSRecursiveLock alloc]init];
    timeBefore = CFAbsoluteTimeGetCurrent();
    for(i=0; i<count; i++){
        [recursiveLock lock];
        [recursiveLock unlock];
    }
    timeCurrent = CFAbsoluteTimeGetCurrent();
    printf("NSRecursiveLock  : %f\n", timeCurrent-timeBefore);
<a name="fenced-code-block">pthread_mutex_t</a>
 pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
    timeBefore = CFAbsoluteTimeGetCurrent();
    for(i=0; i<count; i++){
        pthread_mutex_lock(&mutex);
        pthread_mutex_unlock(&mutex);
    }
    timeCurrent = CFAbsoluteTimeGetCurrent();
    printf("pthread_mutex  : %f\n", timeCurrent-timeBefore);
<a name="fenced-code-block">dispatch_semaphore_t</a>
    dispatch_semaphore_t semaphore = dispatch_semaphore_create(1);
    timeBefore = CFAbsoluteTimeGetCurrent();
    for(i=0; i<count; i++){
        dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
        dispatch_semaphore_signal(semaphore);
    }
    timeCurrent = CFAbsoluteTimeGetCurrent();
    printf("dispatch_semaphore  : %f\n", timeCurrent-timeBefore);
<a name="fenced-code-block">OSSpinLock</a>
    OSSpinLock spinlock = OS_SPINLOCK_INIT;
    timeBefore = CFAbsoluteTimeGetCurrent();
    for(i=0; i<count; i++){
        OSSpinLockLock(&spinlock);
        OSSpinLockUnlock(&spinlock);
    }
    timeCurrent = CFAbsoluteTimeGetCurrent();
    printf("OSSpinLock  : %f\n", timeCurrent-timeBefore);
上一篇下一篇

猜你喜欢

热点阅读