Skip to content

Instantly share code, notes, and snippets.

@javanli
Created October 22, 2019 17:10
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
Star You must be signed in to star a gist
Save javanli/ab51bfc45e3dcccbf743caf88df44e34 to your computer and use it in GitHub Desktop.
iOS lock benchmark
//
// JFDemosTests.m
// JFDemosTests
//
// Created by javanli on 2019/4/26.
// Copyright © 2019年 javanli. All rights reserved.
//
#import <XCTest/XCTest.h>
#import <pthread.h>
#import <libkern/OSAtomic.h>
#import <QuartzCore/QuartzCore.h>
#import <os/lock.h>
@interface JFDemosTests : XCTestCase
@end
static long long i = 0;
@implementation JFDemosTests
{
}
- (void)setUp {
// Put setup code here. This method is called before the invocation of each test method in the class.
}
- (void)tearDown {
// Put teardown code here. This method is called after the invocation of each test method in the class.
}
- (void)logic
{
i++;
}
typedef void (^LockBlock_t)(void);
- (void)benchMark:(LockBlock_t)block
{
int operations = 10;
int logics = 100000;
NSOperationQueue *queue = [[NSOperationQueue alloc] init];
queue.maxConcurrentOperationCount = operations;
[self measureBlock:^{
NSMutableArray *operationArr = [NSMutableArray arrayWithCapacity:operations];
for (int j = 0;j < operations; j++) {
NSBlockOperation *blockOperation = [NSBlockOperation blockOperationWithBlock:^{
for (int i = 0; i < logics; i++) {
block();
}
}];
[operationArr addObject:blockOperation];
}
[queue addOperations:operationArr waitUntilFinished:YES];
XCTAssertTrue(i % operations*logics == 0, "num true");
}];
}
- (void)testSpinLock {
__block OSSpinLock lock = OS_SPINLOCK_INIT;
[self benchMark:^() {
OSSpinLockLock(&lock);
[self logic];
OSSpinLockUnlock(&lock);
}];
}
- (void)testUnfairLock
{
__block os_unfair_lock lock = OS_UNFAIR_LOCK_INIT;
[self benchMark:^() {
os_unfair_lock_lock(&lock);
[self logic];
os_unfair_lock_unlock(&lock);
}];
}
- (void)testSemaphoreLock
{
__block dispatch_semaphore_t lock = dispatch_semaphore_create(1);
[self benchMark:^() {
dispatch_semaphore_wait(lock, DISPATCH_TIME_FOREVER);
[self logic];
dispatch_semaphore_signal(lock);
}];
}
- (void)testMutexLock
{
__block pthread_mutex_t lock;
pthread_mutex_init(&lock, NULL);
[self benchMark:^() {
pthread_mutex_lock(&lock);
[self logic];
pthread_mutex_unlock(&lock);
}];
}
- (void)testCondition
{
NSCondition *lock = [NSCondition new];
[self benchMark:^() {
[lock lock];
[self logic];
[lock unlock];
}];
}
- (void)testNSLock
{
NSLock *lock = [NSLock new];
[self benchMark:^() {
[lock lock];
[self logic];
[lock unlock];
}];
}
- (void)testPthreadMutexLock
{
__block pthread_mutex_t lock;
pthread_mutexattr_t attr;
pthread_mutexattr_init(&attr);
pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
pthread_mutex_init(&lock, &attr);
pthread_mutexattr_destroy(&attr);
[self benchMark:^() {
pthread_mutex_lock(&lock);
[self logic];
pthread_mutex_unlock(&lock);
}];
}
- (void)testNSRecursiveLock
{
NSRecursiveLock *lock = [NSRecursiveLock new];
[self benchMark:^() {
[lock lock];
[self logic];
[lock unlock];
}];
}
- (void)testNSConditionLock
{
NSConditionLock *lock = [[NSConditionLock alloc] initWithCondition:1];
[self benchMark:^() {
[lock lock];
[self logic];
[lock unlock];
}];
}
- (void)testSynchronized
{
NSObject *lock = [NSObject new];
[self benchMark:^() {
@synchronized(lock) {
[self logic];
}
}];
}
@end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment