ios – NSArray vs C Array性能比较

ios – NSArray vs C Array性能比较,第1张

概述我最近在关于C Array的序列或随机访问NSArray的性能方面进行了一些研究项目.大多数测试用例都显示出来,因为我会期望,但是有一些测试用例无法工作,我以为他会这样做,我希望有人能够解释为什么. 从根本上说,测试包括用一个50k个对象填充一个C数组,遍历每一个对象并调用一个方法(内部只是增加一个对象中的一个浮点数),第二部分的测试涉及到创建一个完成50k次迭代但是访问的循环数组中的随机对象.基 我最近在关于C Array的序列或随机访问NSArray的性能方面进行了一些研究项目.大多数测试用例都显示出来,因为我会期望,但是有一些测试用例无法工作,我以为他会这样做,我希望有人能够解释为什么.

从根本上说,测试包括用一个50k个对象填充一个C数组,遍历每一个对象并调用一个方法(内部只是增加一个对象中的一个浮点数),第二部分的测试涉及到创建一个完成50k次迭代但是访问的循环数组中的随机对象.基本上这很简单

要做比较,我用C Array初始化NSArray.然后,每个测试通过传递给跟踪执行块所需的时间的方法运行.我使用的代码包含在下面,但我想覆盖我先前的结果和查询.

这些测试在iPhone 4上运行,并包装在一个dispatch_after中,以缓解由于启动应用程序而导致的任何剩余的线程或非原子 *** 作.单次运行的结果如下,每个运行与较小的变化基本相同:

===SEQUENCE===NSARRAY FAST ENUMERATION: 12msNSARRAY FAST ENUMERATION WEAK: 186msNSARRAY BLOCK ENUMERATION: 31ms (258.3%)C ARRAY DIRECT: 7ms (58.3%)C ARRAY VARIABLE ASSIGN: 33ms (275.0%)C ARRAY VARIABLE ASSIGN WEAK: 200ms (1666.7%)===RANDOM===NSARRAY RANDOM: 102ms (850.0%) *relative to fast enumerationC ARRAY DIRECT RANDOM: 39ms (38.2%) *relative to NSArray RandomC ARRAY VARIABLE ASSIGN RANDOM: 82ms (80.4%)

最快的方法似乎是使用“*(carray IDx)”直接访问C数组中的项目,但最令人困惑的是将指针从C数组分配给目标c变量“ID object = *(carry IDx )“造成了巨大的表现.

我最初想到的是,可能电弧做参数计数,因为变量是强的,所以在这一点上,我将其改为弱,期望性能增加“__weak ID object = *(carry IDx)”.令我吃惊的是,实际上要慢一些.

随机访问结果非常好,我根据顺序结果预期,所以没有什么惊喜,幸运的是.

结果是有一些问题:

>为什么分配给变量需要这么长时间?
>为什么分配到弱变量需要更长时间? (也许这里有一些我不明白的东西)
>考虑到上述情况,苹果如何获得标准的快速枚举来表现得如此之好?

为了完整,这里是代码.所以我创建的阵列如下:

__block ID __strong *cArrayData = (ID __strong *)malloc(sizeof(ID) * ITEM_COUNT);for (NSUInteger IDx = 0; IDx < ITEM_COUNT; IDx ++) {    NSTestObject *object = [[NSTestObject alloc] init];    cArrayData[IDx] = object;}__block NSArray *arrayData = [NSArray arrayWithObjects:cArrayData count:ITEM_COUNT];

而NSTestObject是这样定义的:

@interface NSTestObject : NSObject- (voID)doSomething;@end@implementation NSTestObject{    float f;}- (voID)doSomething{    f++;}

和用于配置代码的方法:

int machTimetoMS(uint64_t machTime){    const int64_t kOneMillion = 1000 * 1000;    static mach_timebase_info_data_t s_timebase_info;    if (s_timebase_info.denom == 0) {        (voID) mach_timebase_info(&s_timebase_info);    }    return (int)((machTime * s_timebase_info.numer) / (kOneMillion * s_timebase_info.denom));}- (int)profile:(dispatch_block_t)call name:(Nsstring *)name benchmark:(int)benchmark{    uint64_t startTime,stopTime;    startTime = mach_absolute_time();    call();    stopTime = mach_absolute_time();    int duration = machTimetoMS(stopTime - startTime);    if (benchmark > 0) {        NSLog(@"%@: %i (%0.1f%%)",name,duration,((float)duration / (float)benchmark) * 100.0f);    } else {        NSLog(@"%@: %i",duration);    }    return duration;}

最后这是我如何执行实际测试:

int benchmark = [self profile:^ {    for (NSTestObject *vIEw in arrayData) {        [vIEw doSomething];    }} name:@"NSARRAY FAST ENUMERATION" benchmark:0];[self profile:^ {    for (NSTestObject __weak *vIEw in arrayData) {        [vIEw doSomething];    }} name:@"NSARRAY FAST ENUMERATION WEAK" benchmark:0];[self profile:^ {    [arrayData enumerateObjectsUsingBlock:^(NSTestObject *vIEw,NSUInteger IDx,BOol *stop) {        [vIEw doSomething];    }];} name:@"NSARRAY BLOCK ENUMERATION" benchmark:benchmark];[self profile:^ {    for (NSUInteger IDx = 0; IDx < ITEM_COUNT; IDx ++) {        [*(cArrayData + IDx) doSomething];    }} name:@"C ARRAY DIRECT" benchmark:benchmark];[self profile:^ {    ID object = nil;    NSUInteger IDx = 0;    while (IDx < ITEM_COUNT) {        object = (ID)*(cArrayData + IDx);        [object doSomething];        object = nil;        IDx++;    }} name:@"C ARRAY VARIABLE ASSIGN" benchmark:benchmark];[self profile:^ {    __weak ID object = nil;    NSUInteger IDx = 0;    while (IDx < ITEM_COUNT) {        object = (ID)*(cArrayData + IDx);        [object doSomething];        object = nil;        IDx++;    }} name:@"C ARRAY VARIABLE ASSIGN WEAK" benchmark:benchmark];NSLog(@"\n===RANDOM===\n");benchmark = [self profile:^ {    ID object = nil;    for (NSUInteger IDx = 0; IDx < ITEM_COUNT; IDx ++) {        object = arrayData[arc4random()%ITEM_COUNT];        [object doSomething];    }} name:@"NSARRAY RANDOM" benchmark:benchmark];[self profile:^ {    NSUInteger IDx = 1;    while (IDx < ITEM_COUNT) {        [*(cArrayData + arc4random()%ITEM_COUNT) doSomething];        IDx++;    }} name:@"C ARRAY DIRECT RANDOM" benchmark:benchmark];[self profile:^ {    ID object = nil;    NSUInteger IDx = 0;    while (IDx < ITEM_COUNT) {        object = (ID)*(cArrayData + arc4random()%ITEM_COUNT);        [object doSomething];        IDx++;    }} name:@"C ARRAY VARIABLE ASSIGN RANDOM" benchmark:benchmark];
解决方法

Why does assigning to a variable take so long?

您的猜测是正确的:当您分配时,ARC调用保留,并在重新分配时释放,或者ID超出范围时.

Why does assigning to a weak variable take even longer? (Maybe there is something I don’t understand going on here)

回想一下,当最后一次强烈的参考消息时,ARC承诺清除你的弱参考.这就是为什么弱引用更昂贵:为了没有__weak ID,ARC将ID的地址注册到运行时以获取正在释放的对象的通知.这种注册需要写入哈希表 – 远远慢于保留和释放.

ConsIDering the above how have Apple got the standard fast enumeration to perform so well?

快速枚举使用直接支持NSArray的数组块.实质上,他们抓住30个元素的块,并将其作为普通C数组访问.然后他们抓住下一个块,迭代它,好像它是一个C数组,等等.有一些小的开销,但它是每个块,而不是每个元素,所以你得到一个非常令人印象深刻的表现.

总结

以上是内存溢出为你收集整理的ios – NSArray vs C Array性能比较全部内容,希望文章能够帮你解决ios – NSArray vs C Array性能比较所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/web/1110442.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-29
下一篇 2022-05-29

发表评论

登录后才能评论

评论列表(0条)

保存