iOS 关于锁的性能测试结果

最近因为程序中频繁使用到了锁,不知道各种锁对性能的影响,今天稍作测试(测试维度少的一笔)


测试原理:在一个线程中,对空代码段执行指定次数的加解锁。算出时间差。

自己测试结果:NSLock 和pthread_mutex_lock 在自锁次数较少时,性能相近,后者略好.自旋锁性能比前面两个高一个数量级别.dispatch_semaphore和自选锁性能相近,但自旋锁表现更优

 OSSpinlock: 10.666013 ms

 @synchronized: 224.983037 ms

 NSlock: 94.928026 ms

 pthread_mutex_lock: 67.334950 ms

 dispatch_semaphore: 17.728031 ms

忙活半天发现有文献:

@synchronized

创建给@synchronized指令的对象是一个用来区别保护块的唯一标示符。如果你在两个不同的线程里面执行上述方法,每次在一个线程传递了一个不同的对象给anObj参数,那么每次都将会拥有它的锁,并持续处理,中间不被其他线程阻塞。然而,如果你传递的是同一个对象,那么多个线程中的一个线程会首先获得该锁,而其他线程将会被阻塞直到第一个线程完成它的临界区。

作为一种预防措施,@synchronized块隐式的添加一个异常处理例程来保护代码。该处理例程会在异常抛出的时候自动的释放互斥锁。这意味着为了使用@synchronized指令,你必须在你的代码中启用异常处理。了如果你不想让隐式的异常处理例程带来额外的开销,你应该考虑使用锁的类。

OSSpinlock 官方描述(自旋锁)

Spin locks are a simple, fast, thread-safe synchronization primitive that is suitable in situations

where contention is expected to be low. The spinlock operations use memory barriers to synchronize

access to shared memory protected by the lock. Preemption is possible while the lock is held.

摘自:yycache

OSSpinLock 自旋锁,性能最高的锁。原理很简单,就是一直 do while 忙等。它的缺点是当等待时会消耗大量 CPU 资源,所以它不适用于较长时间的任务。对于内存缓存的存取来说,它非常合适

dispatch_semaphore 是信号量,但当信号总量设为 1 时也可以当作锁来。在没有等待情况出现时,它的性能比 pthread_mutex 还要高,但一旦有等待情况出现时,性能就会下降许多。相对于 OSSpinLock 来说,它的优势在于等待时不会消耗 CPU 资源。对磁盘缓存来说.(原作者的diskCache中采用semaphore)

测试代码:


OSSpinLock spinLock =OS_SPINLOCK_INIT ;

pthread_mutex_t  metext = PTHREAD_MUTEX_INITIALIZER ;

NSLock *lock = [NSLock new];

id obj = [NSObject new];

dispatch_semaphore_t  _lockSemaphore = dispatch_semaphore_create(1);

int runTimes = 1000000;

@autoreleasepool {

//#import  

double_t lastTime = CFAbsoluteTimeGetCurrent() ;

for (int i=0 ; i < runTimes; i++) {

OSSpinLockLock(&spinLock);

OSSpinLockUnlock(&spinLock);

}

double_t curTime = CFAbsoluteTimeGetCurrent() ;

NSLog(@"OSSpinlock: %f ms",(curTime - lastTime)*1000);

//@synchronized 不用导入

lastTime = CFAbsoluteTimeGetCurrent() ;

for (int i=0 ; i < runTimes; i++) {

@synchronized(obj) {

}

}

curTime = CFAbsoluteTimeGetCurrent() ;

NSLog(@"@synchronized: %f ms",(curTime - lastTime)*1000);

//NSlock 不用导入

lastTime = CFAbsoluteTimeGetCurrent() ;

for (int i=0 ; i < runTimes; i++) {

[lock lock];

[lock unlock];

}

curTime = CFAbsoluteTimeGetCurrent() ;

NSLog(@"NSlock: %f ms",(curTime - lastTime)*1000);

// pthread_mutex_lock #import

lastTime = CFAbsoluteTimeGetCurrent() ;

for (int i=0 ; i < runTimes; i++) {

pthread_mutex_lock(&metext);

pthread_mutex_unlock(&metext);

}

curTime = CFAbsoluteTimeGetCurrent() ;

NSLog(@"pthread_mutex_lock: %f ms",(curTime - lastTime)*1000);

// dispatch_semaphore

lastTime = CFAbsoluteTimeGetCurrent() ;

for (int i=0 ; i < runTimes; i++) {

dispatch_semaphore_wait(_lockSemaphore, DISPATCH_TIME_FOREVER);

dispatch_semaphore_signal(_lockSemaphore);

}

curTime = CFAbsoluteTimeGetCurrent() ;

NSLog(@"dispatch_semaphore: %f ms",(curTime - lastTime)*1000);

}

你可能感兴趣的:(iOS 关于锁的性能测试结果)