iOS 锁的性能测试

 前言:OSSpinLock 性能真的很高?
 @synchronize 性能真的很差?
 OSSpinLock 的替代品 os_unfair_lock很高?

ibireme 的结论真的对吗?

1、主线程中测试代码:(测试环境:iPhone 7  iOS 13.4 MAC OS 10.15.4 xCode 11.4)

1.1、通过clock_gettime() 转换为微秒时间进行比较 ,通过在主线程中分别尝试10000次加锁,解锁操作 得出diff:

static uint32_t getCurrentTimeIntervalMicrosecond()
{
    struct timespec         time = {0, 0};
    clock_gettime(CLOCK_MONOTONIC, &time);
    
    return (uint32_t)(time.tv_sec * 1000000 + time.tv_nsec / 1000);
}

- (void)spinLockTest{
    uint32_t before = getCurrentTimeIntervalMicrosecond();
    OSSpinLock spinLock = OS_SPINLOCK_INIT;
    for (int i = 0; i < 10000;) {
        OSSpinLockLock(&spinLock);
        i++;
        OSSpinLockUnlock(&spinLock);
    }
    NSLog(@"spinLock time:%d",getCurrentTimeIntervalMicrosecond() - before);
}

- (void)os_unfair_lock_test{
    uint32_t before = getCurrentTimeIntervalMicrosecond();
    os_unfair_lock osUnfairLock = OS_UNFAIR_LOCK_INIT;
    for (int i = 0; i < 10000;) {
      os_unfair_lock_lock(&osUnfairLock);
      i++;
      os_unfair_lock_unlock(&osUnfairLock);
    }
    NSLog(@"osUnfairLock time:%d",getCurrentTimeIntervalMicrosecond() - before);
}


- (void)os_unfair_lock_try_test{
    uint32_t before = getCurrentTimeIntervalMicrosecond();
    os_unfair_lock osUnfairLock = OS_UNFAIR_LOCK_INIT;
    for (int i = 0; i < 10000;) {
      if (os_unfair_lock_trylock(&osUnfairLock)) {
          i++;
          os_unfair_lock_unlock(&osUnfairLock);
      }
    }
    NSLog(@"osUnfairTryLock time:%d",getCurrentTimeIntervalMicrosecond() - before);
}

- (void)pthread_mutex_normal_test{
    uint32_t before = getCurrentTimeIntervalMicrosecond();
    pthread_mutex_t normal_mutex;
    pthread_mutexattr_t attr;
    pthread_mutexattr_init(&attr);
    pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_NORMAL);
    pthread_mutex_init(&normal_mutex, &attr);
      for (int i = 0; i < 10000;) {
          pthread_mutex_lock(&normal_mutex);
          i++;
          pthread_mutex_unlock(&normal_mutex);
      }
      NSLog(@"PTHREAD_MUTEX_NORMALdiff time:%d",getCurrentTimeIntervalMicrosecond() - before);
    pthread_mutexattr_destroy(&attr);
    pthread_mutex_destroy(&normal_mutex);
}

- (void)pthread_mutex_recursive_test{
    uint32_t before = getCurrentTimeIntervalMicrosecond();
    pthread_mutex_t normal_mutex;
    pthread_mutexattr_t attr;
    pthread_mutexattr_init(&attr);
    pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
    pthread_mutex_init(&normal_mutex, &attr);
    for (int i = 0; i < 10000;) {
        pthread_mutex_lock(&normal_mutex);
        i++;
        pthread_mutex_unlock(&normal_mutex);
    }
    NSLog(@"PTHREAD_MUTEX_RECURSIVE diff time:%d",getCurrentTimeIntervalMicrosecond() - before);
    pthread_mutexattr_destroy(&attr);
    pthread_mutex_destroy(&normal_mutex);
}

- (void)nslockTest{
    uint32_t before = getCurrentTimeIntervalMicrosecond();
    NSLock* lock = NSLock.new;
    for (int i = 0; i < 10000;) {
        [lock lock];
        i++;
        [lock unlock];
    }
    NSLog(@"NSLock diff time:%d",getCurrentTimeIntervalMicrosecond() - before);
}

- (void)nsRecursiveLockTest{
    uint32_t before = getCurrentTimeIntervalMicrosecond();
    NSRecursiveLock* lock = NSRecursiveLock.new;
    for (int i = 0; i < 10000;) {
        [lock lock];
        i++;
        [lock unlock];
    }
    NSLog(@"NSRecursiveLock time:%d",getCurrentTimeIntervalMicrosecond() - before);
}

- (void)nslockConditionTest{
    uint32_t before = getCurrentTimeIntervalMicrosecond();
    NSCondition* lock = NSCondition.new;
    for (int i = 0; i < 10000;) {
        [lock lock];
        i++;
        [lock unlock];
    }
    NSLog(@"NSCondition diff time:%d",getCurrentTimeIntervalMicrosecond() - before);
}

- (void)nslockConditionLockTest{
    uint32_t before = getCurrentTimeIntervalMicrosecond();
    NSConditionLock* lock = [[NSConditionLock alloc] initWithCondition:0];
    for (int i = 0; i < 10000;) {
        [lock lockWhenCondition:i];
        i++;
        [lock unlockWithCondition:i];
      
    }
    NSLog(@"NSConditionLock lock diff time:%d",getCurrentTimeIntervalMicrosecond() - before);
}

- (void)synchronizeTest{
    uint32_t before = getCurrentTimeIntervalMicrosecond();
    NSNumber* number = @(100);
    for (int i = 0; i < 10000;) {
        @synchronized (number) {
            i++;
        }
      
    }
    NSLog(@"synchronize diff time:%d",getCurrentTimeIntervalMicrosecond() - before);
}

1.2、测试结果:

 

2、异步在全局并发队列中执行10000次并打印结果,打印时间为毫秒:

2.1、测试代码:

//毫秒
static uint32_t getCurrentTimeIntervalMicrosecond()
{
    struct timespec         time = {0, 0};
    clock_gettime(CLOCK_MONOTONIC, &time);
    
    return (uint32_t)(time.tv_sec * 1000 + time.tv_nsec / 1000000);
}

- (void)spinLockTest{
    uint32_t before = getCurrentTimeIntervalMicrosecond();
    static OSSpinLock spinLock = OS_SPINLOCK_INIT;
    dispatch_group_t group = dispatch_group_create();
    for (int i = 0; i < 10000;) {
        dispatch_group_async(group, dispatch_get_global_queue(0, 0), ^{
             OSSpinLockLock(&spinLock);
             g_global_variable = i;
             //NSLog(@"__%s__:g_global_variable = %d",__func__,g_global_variable);
             OSSpinLockUnlock(&spinLock);
        });
        i++;
    }
    dispatch_group_notify(group, dispatch_get_main_queue(), ^{
        NSLog(@"result spinLockTest diff time:%d",getCurrentTimeIntervalMicrosecond() - before);
    });
    
}

- (void)os_unfair_lock_test{
    uint32_t before = getCurrentTimeIntervalMicrosecond();
    static os_unfair_lock osUnfairLock = OS_UNFAIR_LOCK_INIT;
    dispatch_group_t group = dispatch_group_create();
    for (int i = 0; i < 10000;) {
         dispatch_group_async(group,dispatch_get_global_queue(0, 0), ^{
            os_unfair_lock_lock(&osUnfairLock);
            g_global_variable = i;
            //NSLog(@"__%s__:g_global_variable = %d",__func__,g_global_variable);
            os_unfair_lock_unlock(&osUnfairLock);
        });
        i++;
    }
    dispatch_group_notify(group, dispatch_get_main_queue(), ^{
        NSLog(@"result os_unfair_lock_test diff time:%d",getCurrentTimeIntervalMicrosecond() - before);
    });
}


- (void)os_unfair_lock_try_test{
    uint32_t before = getCurrentTimeIntervalMicrosecond();
    static os_unfair_lock osUnfairLock = OS_UNFAIR_LOCK_INIT;
    dispatch_group_t group = dispatch_group_create();
    for (int i = 0; i < 10000;) {
         dispatch_group_async(group,dispatch_get_global_queue(0, 0), ^{
         if (os_unfair_lock_trylock(&osUnfairLock)) {
             g_global_variable = i;
             //NSLog(@"__%s__:g_global_variable = %d",__func__,g_global_variable);
             os_unfair_lock_unlock(&osUnfairLock);
         }
        });
        i++;
    }
    dispatch_group_notify(group, dispatch_get_main_queue(), ^{
        NSLog(@"result os_unfair_lock_try_test diff time:%d",getCurrentTimeIntervalMicrosecond() - before);
    });
}

- (void)pthread_mutex_normal_test{
    uint32_t before = getCurrentTimeIntervalMicrosecond();
    static pthread_mutex_t normal_mutex;
    static pthread_mutexattr_t attr;
    pthread_mutexattr_init(&attr);
    pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_NORMAL);
    pthread_mutex_init(&normal_mutex, &attr);
    dispatch_group_t group = dispatch_group_create();
    for (int i = 0; i < 10000;) {
         dispatch_group_async(group,dispatch_get_global_queue(0, 0), ^{
            pthread_mutex_lock(&normal_mutex);
            g_global_variable = i;
            //NSLog(@"__%s__:g_global_variable = %d",__func__,g_global_variable);
            pthread_mutex_unlock(&normal_mutex);
        });
        i++;
    }
    dispatch_group_notify(group, dispatch_get_main_queue(), ^{
        NSLog(@"result pthread_mutex_normal_test diff time:%d",getCurrentTimeIntervalMicrosecond() - before);
    });
}

- (void)pthread_mutex_recursive_test{
    uint32_t before = getCurrentTimeIntervalMicrosecond();
    static pthread_mutex_t normal_mutex;
    static pthread_mutexattr_t attr;
    pthread_mutexattr_init(&attr);
    pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
    pthread_mutex_init(&normal_mutex, &attr);
    dispatch_group_t group = dispatch_group_create();
    for (int i = 0; i < 10000;) {
         dispatch_group_async(group,dispatch_get_global_queue(0, 0), ^{
            pthread_mutex_lock(&normal_mutex);
            g_global_variable = i;
            //NSLog(@"__%s__:g_global_variable = %d",__func__,g_global_variable);
            pthread_mutex_unlock(&normal_mutex);
        });
        i++;
    }
    dispatch_group_notify(group, dispatch_get_main_queue(), ^{
        NSLog(@"result pthread_mutex_recursive_test diff time:%d",getCurrentTimeIntervalMicrosecond() - before);
    });
}

- (void)nslockTest{
    uint32_t before = getCurrentTimeIntervalMicrosecond();
    NSLock* lock = NSLock.new;
    dispatch_group_t group = dispatch_group_create();
    for (int i = 0; i < 10000;) {
         dispatch_group_async(group,dispatch_get_global_queue(0, 0), ^{
            [lock lock];
            g_global_variable = i;
            //NSLog(@"__%s__:g_global_variable = %d",__func__,g_global_variable);
            [lock unlock];
        });
        i++;
    }
    dispatch_group_notify(group, dispatch_get_main_queue(), ^{
        NSLog(@"result nslockTest diff time:%d",getCurrentTimeIntervalMicrosecond() - before);
    });
}

- (void)nsRecursiveLockTest{
    uint32_t before = getCurrentTimeIntervalMicrosecond();
    NSRecursiveLock* lock = NSRecursiveLock.new;
    dispatch_group_t group = dispatch_group_create();
    for (int i = 0; i < 10000;) {
         dispatch_group_async(group,dispatch_get_global_queue(0, 0), ^{
            [lock lock];
            g_global_variable = i;
            //NSLog(@"__%s__:g_global_variable = %d",__func__,g_global_variable);
            [lock unlock];
        });
        i++;
    }
    
    dispatch_group_notify(group, dispatch_get_main_queue(), ^{
        NSLog(@"result nsRecursiveLockTest diff time:%d",getCurrentTimeIntervalMicrosecond() - before);
    });
}

- (void)nslockConditionTest{
    uint32_t before = getCurrentTimeIntervalMicrosecond();
    NSCondition* lock = NSCondition.new;
    dispatch_group_t group = dispatch_group_create();
    for (int i = 0; i < 10000;) {
         dispatch_group_async(group,dispatch_get_global_queue(0, 0), ^{
            [lock lock];
            g_global_variable = i;
            //NSLog(@"__%s__:g_global_variable = %d",__func__,g_global_variable);
            [lock unlock];
        });
        i++;
    }
    
    dispatch_group_notify(group, dispatch_get_main_queue(), ^{
        NSLog(@"result nslockConditionTest diff time:%d",getCurrentTimeIntervalMicrosecond() - before);
    });
}

- (void)nslockConditionLockTest{
    uint32_t before = getCurrentTimeIntervalMicrosecond();
    NSConditionLock* lock = [[NSConditionLock alloc] initWithCondition:0];
    dispatch_group_t group = dispatch_group_create();
    for (int i = 0; i < 10000;) {
         dispatch_group_async(group,dispatch_get_global_queue(0, 0), ^{
            [lock lockWhenCondition:i];
            g_global_variable = i;
            //NSLog(@"__%s__:g_global_variable = %d",__func__,g_global_variable);
            [lock unlockWithCondition:(i + 1)];
        });
        i++;
    }
    dispatch_group_notify(group, dispatch_get_main_queue(), ^{
        NSLog(@"result nslockConditionLockTest diff time:%d",getCurrentTimeIntervalMicrosecond() - before);
    });
}

- (void)synchronizeTest{
    uint32_t before = getCurrentTimeIntervalMicrosecond();
    NSNumber* number = @(100);
    dispatch_group_t group = dispatch_group_create();
    for (int i = 0; i < 10000;) {
         dispatch_group_async(group,dispatch_get_global_queue(0, 0), ^{
            @synchronized(@(i)){
                g_global_variable = i;
                //NSLog(@"__%s__:g_global_variable = %d",__func__,g_global_variable);
            };
        });
        i++;
    }
    dispatch_group_notify(group, dispatch_get_main_queue(), ^{
        NSLog(@"result synchronizeTest diff time:%d",getCurrentTimeIntervalMicrosecond() - before);
    });
}

2.2、惊奇发现调用顺序会影响结论,所以此结论不准:

2.3、每次启动单独调用某一个锁10000次:

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在进行iOS系统性能测试时,可以采取以下步骤: 1. 准备一台MAC电脑,并安装最新的操作系统。然后下载并安装Xcode,这是进行iOS开发和性能测试的必备工具。 2. 下载并配置WebDriverAgent,这是一个可以启动app的工具。在配置过程中,需要填写一个开发账号,并连接手机。配置完成后,运行WebDriverAgent,如果成功的话,手机上会出现一个Integration App的应用。 3. 打开Xcode,并选择Instruments。Instruments是一个性能测试工具,可以用来监测和分析iOS应用的性能。 4. 在Instruments中选择你想要跑的指标,比如APPLaunch,这是一个衡量应用启动时间的指标。 5. 运行测试,并查看测试结果。根据结果,可以与开发团队一起分析是否存在性能问题,并进行优化。除了启动时间,还可以跑其他指标,根据需要选择相应的指标进行测试。 需要注意的是,在进行性能对比实验时,要尽量保持实验场景的一致性,或者取大量真实数据的平均值。然而,由于用户的真实使用场景很难完全一样,可能会受到多种因素的影响,比如网络状况、硬件、系统版本、设备可用空间以及同时运行的其他应用等\[2\]。 此外,Instrument还可以与UI Test配合使用,通过脚本记录用户行为序列,实现可重复多次的自动化测试。这个脚本是由Xcode自动生成的,不需要程序员手动编写\[3\]。 希望以上信息对您有所帮助! #### 引用[.reference_title] - *1* [APP性能测试IOS性能测试-instruments使用](https://blog.csdn.net/Marry_Ma/article/details/121765175)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* *3* [《iOS APP 性能检测》](https://blog.csdn.net/xxq_2011/article/details/78129298)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值