首页 / 知识

关于C#:NSEnumerator性能与可可中的for循环

2023-04-13 12:50:00

NSEnumerator performance vs for loop in Cocoa

我知道,如果您有一个循环来修改循环中项目的计数,则在集合上使用NSEnumerator是确保代码爆炸的最佳方法,但是我想了解NSEnumerator类之间的性能折衷 还有一所老学校


通常,在Objective-C 2.0中使用新的for (... in ...)语法是对集合进行迭代的最快方法,因为它可以在堆栈上维护一个缓冲区并将大量项目放入其中。

使用NSEnumerator通常是最慢的方法,因为它通常会复制要迭代的集合。对于不可变的集合,这可能很便宜(相当于-retain),但是对于可变的集合,这可能会导致创建不可变的副本。

进行自己的迭代(例如,使用-[NSArray objectAtIndex:])通常会介于两者之间,因为虽然您没有潜在的复制开销,但是您也不会从基础集合中获取一批对象。

(PS-此问题应标记为Objective-C,而不是C,因为NSEnumerator是Cocoa类,并且新的for (... in ...)语法特定于Objective-C。)


多次运行测试后,结果几乎相同。每个测量块连续运行10次。

在我的情况下,结果从最快到最慢:

  • For..in(testPerformanceExample3)(0.006秒)
  • While(testPerformanceExample4)(0.026秒)
  • For(;;)(testPerformanceExample1)(0.027秒)
  • 枚举块(testPerformanceExample2)(0.067秒)
  • for和while循环几乎相同。

    comparation between iterations

    tmpNSArray,其中包含1百万个对象,范围从0到999999。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    - (NSArray *)createArray
    {
        self.tmpArray = [NSMutableArray array];
        for (int i = 0; i < 1000000; i++)
        {
            [self.tmpArray addObject:@(i)];
        }
        return self.tmpArray;
    }

    整个代码:

    ViewController.h

    1
    2
    3
    4
    5
    6
    7
    8
    #import <UIKit/UIKit.h>

    @interface ViewController : UIViewController

    @property (strong, nonatomic) NSMutableArray *tmpArray;
    - (NSArray *)createArray;

    @end

    ViewController.m

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    #import"ViewController.h"

    @implementation ViewController

    - (void)viewDidLoad {
        [super viewDidLoad];
        [self createArray];
    }

    - (NSArray *)createArray
    {
        self.tmpArray = [NSMutableArray array];
        for (int i = 0; i < 1000000; i++)
        {
            [self.tmpArray addObject:@(i)];
        }
        return self.tmpArray;
    }

    @end

    MyTestfile.m

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    #import <UIKit/UIKit.h>
    #import <XCTest/XCTest.h>

    #import"ViewController.h"

    @interface TestCaseXcodeTests : XCTestCase
    {
        ViewController *vc;
        NSArray *tmp;
    }

    @end

    @implementation TestCaseXcodeTests

    - (void)setUp {
        [super setUp];
        vc = [[ViewController alloc] init];
        tmp = vc.createArray;
    }

    - (void)testPerformanceExample1
    {
        [self measureBlock:^{
            for (int i = 0; i < [tmp count]; i++)
            {
                [tmp objectAtIndex:i];
            }
        }];
    }

    - (void)testPerformanceExample2
    {
        [self measureBlock:^{
            [tmp enumerateObjectsUsingBlock:^(NSNumber *obj, NSUInteger idx, BOOL *stop) {
               obj;
            }];
        }];
    }

    - (void)testPerformanceExample3
    {
        [self measureBlock:^{
            for (NSNumber *num in tmp)
            {
                num;
            }
        }];
    }

    - (void)testPerformanceExample4
    {
        [self measureBlock:^{
            int i = 0;
            while (i < [tmp count])
            {
                [tmp objectAtIndex:i];
                i++;
            }
        }];
    }

    @end

    有关更多信息,请访问:苹果公司"关于使用Xcode进行测试"


    它们非常相似。现在,使用Objective-C 2.0时,大多数枚举默认为NSFastEnumeration,这将为该集合中的每个对象创建一个地址缓冲区,然后可以传递该地址。通过经典的for循环保存的一个步骤是不必在循环内每次都调用objectAtIndex:i。您要枚举的集合的内部实现了快速枚举,而无需调用objectAtIndex:i method

    缓冲区是您无法在枚举时对集合进行变异的部分原因,对象的地址将更改,并且已建立的缓冲区将不再匹配。

    另外,2.0中的格式看起来像经典的for循环一样好:

    1
    2
    3
    for ( Type newVariable in expression ) {
        stmts
    }

    阅读以下文档以更深入了解:
    NSFastEnumeration协议参考


    循环性能项目修改

    最新内容

    相关内容

    热门文章

    推荐文章

    标签云

    猜你喜欢