iOS-测试用例测试数组“firstObject“以及“lastObject“性能-by:nixs

在开发中数组可以说是最常用到的数据结构了,无论是存储对象还是获取沙盒目录数组中文件路径,会经常用到数组的两个对象方法: 即 [xx数组 firstObject] 和 [xx数组 lastObject].
譬如获取沙盒中cache文件夹路径

[NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) firstObject]

[NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject]

因为 NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) 所取到的路径数组只有一个,所以两者皆可获取沙盒中cache路径. 每每使用我都会好奇两个方法哪个性能高一点? 使用iOS测试用例实地测试一下便可.

首先自定义一个工具类 TestTool
声明如下方法

+(NSNumber *)firstNum;
+(NSNumber *)lastNum;
-(NSNumber *)firstNumber;
-(NSNumber *)lastNumber;

并实现

+(NSNumber *)firstNum{
    return [testNumbers firstObject];
}
+(NSNumber *)lastNum{
    return [testNumbers lastObject];
}
-(NSNumber *)firstNumber{
     return [testNumbers firstObject];
}
-(NSNumber *)lastNumber{
    return [testNumbers lastObject];
}

宏定义初始化数组 testNumbers0

#define testNumbers @[@123,@98,@7,@97987,@3456,@0,@87,@456,@66,@12,@90,@9,@678,@4567,@987654,@10010,@6545,@798,@123,@98,@7,@97987,@3456,@0,@87,@456,@66,@12,@90,@9,@678,@4567,@987654,@10010,@6545,@798,@123,@98,@7,@97987,@3456,@0,@87,@456,@66,@12,@90,@9,@678,@4567,@987654,@10010,@6545,@798,@123,@98,@7,@97987,@3456,@0,@87,@456,@66,@12,@90,@9,@678,@4567,@987654,@10010,@6545,@798,@123,@98,@7,@97987,@3456,@0,@87,@456,@66,@12,@90,@9,@678,@4567,@987654,@10010,@6545,@798,@123,@98,@7,@97987,@3456,@0,@87,@456,@66,@12,@90,@9,@678,@4567,@987654,@10010,@6545,@798,@123,@98,@7,@97987,@3456,@0,@87,@456,@66,@12,@90,@9,@678,@4567,@987654,@10010,@6545,@798,@3456,@0,@87,@456,@66,@12,@90,@9,@678,@4567,@987654,@10010,@6545,@798,@123,@98,@7,@97987,@3456,@0,@87,@456,@66,@12,@90,@9,@678,@4567,@987654,@10010,@6545,@798,@123,@98,@7,@97987,@3456,@0,@87,@456,@66,@12,@90,@9,@678,@4567,@987654,@10010,@6545,@798,@123,@98,@7,@97987,@3456,@0,@87,@456,@66,@12,@90,@9,@678,@4567,@987654,@10010,@6545,@798,@123,@98,@7,@97987,@3456,@0,@87,@456,@66,@12,@90,@9,@678,@4567,@987654,@10010,@6545,@798,@123,@98,@7,@97987,@3456,@0,@87,@456,@66,@12,@90,@9,@678,@4567,@987654,@10010,@6545,@798,@123]
  • 1

下面使用测试用例分别使用
[testNumbers firstObject] 和 [testNumbers lastObject] 提取数组中第一个或最后一个元素 123 .为使结果更明显,同样使用for循环提取900000遍,查看耗时.

测试1.测试多数据数组差异

/// 类方法测试 [xx数组 firstObject]
-(void)testPerformanceArrFirst_ClassMethod{
    [self measureBlock:^{
        for (int i = 0; i < 900000; i++) {
            NSNumber *lastNum = [TestTool firstNum];
        }
    }];
    // 多数据数组 - 五次结果分别: 3.517  3.403  3.475 3.516 3.571 平均:3.4964
}

[xx数组 firstObject] : 一个存储多组数据的数组取首元素五次测试值平均耗时 3.4964 秒

/// 类方法测试 lastObject
-(void)testPerformanceArrLast_ClassMethod{
    [self measureBlock:^{
        for (int i = 0; i < 900000; i++) {
            NSNumber *lastNum = [TestTool lastNum];
        }
    }];
    // 多数据数组 - 五次结果分别:3.342  3.282  3.357  3.318  3.359 平均:3.3316
}

[xx数组 lastObject]: 一个存储多组数据的数组取首元素五次测试值平均耗时 3.3316 秒

明显在一个存储有200个数据左右的数组,使用 [xx数组 lastObject] 性能要优于 [xx数组 firstObject]

测试2.测试单数据数组差异

数组更改为:

#define testNumbers @[@123]
  • 1

将上述测试数组更换为只有一个数据的单数据数组, 这样无论[testNumbers0 lastObject] 性还是 [xx数组 firstObject] 取得都是同一个数据,测试两个类方法性能差异

/// 类方法测试 [xx数组 firstObject]
-(void)testPerformanceArrFirst_ClassMethod{
    [self measureBlock:^{
        for (int i = 0; i < 900000; i++) {
            NSNumber *lastNum = [TestTool firstNum];
        }
    }];

    // 单数据数组 - 五次结果分别: 0.198  0.200  0.201 0.201 0.208 平均:0.2016
}

[xx数组 firstObject] : 一个存储单一数据的数组取首元素五次测试值平均耗时 0.2016 秒

/// 类方法测试 lastObject
-(void)testPerformanceArrLast_ClassMethod{
    [self measureBlock:^{
        for (int i = 0; i < 900000; i++) {
            NSNumber *lastNum = [TestTool lastNum];
        }
    }];

    // 单数据数组 - 五次结果分别:0.197  0.195  0.206  0.194  0.197 平均:0.1978
}

[xx数组 lastObject]: 一个存储单一数据的数组取首元素五次测试值平均耗时 0.1978 秒

明显在一个存储有1个数据左右的数组,使用 [xx数组 lastObject] 性能同样也要优于 [xx数组 firstObject]

测试3. 类方法性能和对象方法性能差异

众所周知声明一个类,在类中声明方法可以声明类方法和对象方法, 倘若方法中不会使用类中成员变量和属性,一般建议将方法声明为类方法,因为相同的算法类方法性能要优于对象方法.下面对上述结论进行测试,毕竟耳听为虚.

下面在类方法和对象方法中同样执行 对相同数组(1数据数组) 进行相同 [xx数组 lastObject] 算法
即对比如下两方法

+(NSNumber *)lastNum{
    return [testNumbers lastObject];
}
-(NSNumber *)lastNumber{
    return [testNumbers lastObject];
}

测试用例进行测试

/// 类方法测试 lastObject
-(void)testPerformanceArrLast_ClassMethod{
    [self measureBlock:^{
        for (int i = 0; i < 900000; i++) {
            NSNumber *lastNum = [TestTool lastNum];
        }
    }];

    // 单数据数组 - 五次结果分别:0.197  0.195  0.206  0.194  0.197 平均:0.1978
}

/// 对象方法测试 lastObject
-(void)testPerformanceArrLast_ObjectMethod{
    [self measureBlock:^{
        for (int i = 0; i < 900000; i++) {
            TestTool *tool = [[TestTool alloc] init];
            NSNumber *lastNum = [tool lastNumber];
        }
    }];
    // 单数据数组 - 五次结果分别: 0.333  0.333   0.349  0.350  0.331 平均:0.3392
}

明显类方法性能明显优于对象方法

上一篇:Runtime-iOS运行时基础篇


下一篇:Python之正则re模块 --- findall()详解