Objective-c中的静态变量和性能

时间:2012-01-28 15:38:09

标签: ios performance uitableview static nsarray

在一个有许多不同UITableView的应用程序中,我发现自己经常使用临时数组导入用于填充表视图的数据,确定行数,部分,页眉,页脚等。我想知道是否,因为如果声明静态所以不需要再次创建它们就需要为表中的每个单元格反复创建这些数组将有助于提高性能,因为现在这些数组是在cellForRowAtIndexPath:中创建的,{ {1}},numberOfSectionsInTableView:numberOfRowsInSections: footerForSection:`。从长远来看,声明这么多静态数组(可能包含大量信息,比如几千个双打和几百个字符串)会帮助还是伤害我?我知道静态数组会在应用程序生命周期中保留在内存中,所以这么多静态数组会不会有害吗?假设这个过程在应用程序的整个过程中发生在4-5个视图控制器中,我们正在讨论这个阵列的15-20个副本。我最好的选择是什么?感谢

编辑:我正在使用一个包含值的单例。临时数组的真正原因是保持代码清洁。我可以做点像

,

然后

dataArray = [[SingletonDataController sharedSingleton] dataArray] 
    objectAtIndex:CURRENTLY_SELECTED_DATA_INDEX;

而不是将其全部分组为一个不可读的语句,如:

myTitleString = [dataArray objectAtIndex:keyTitleStringIndexKey]; 

我已经执行了一些自己的测试,比较了使用/不使用静态初始化创建表视图所需的时间。结果如下:

myTitleString = [[[[SingletonDataController sharedSingleton] dataArray] 
    objectAtIndex:CURRENTLY_SELECTED_INDEX] objectAtIndex:keyTitleStringIndexKey];

正如您所看到的,静态初始化实际上比非静态初始,但只有几万分之一秒。这可能只是测量不准确的结果,但结果足以让我相信这种差异足够小,可以解雇。神秘解决了。

1 个答案:

答案 0 :(得分:3)

当你执行上述操作时,实际上并没有创建新数组,只是抓取指向该数组的指针。您没有复制实际数据。

通过保持代码清洁,您只会失去为指针创建内存并为指针赋值的性能。所以不,你没有失去表现。

保持代码清洁的想法比这里和那里的额外指针的边际差异重要得多。


编辑:

我在两者之间进行了一些测试,正如预期的那样,两个选项的表现非常相似。

NSMutableArray *data1 = [[NSMutableArray alloc] init];
NSMutableArray *data2 = [[NSMutableArray alloc] init];
NSArray *all = [[NSArray alloc] initWithObjects:data1,data2,nil];
for(int i=0;i<1000;i++)
{
    [data1 addObject:[[NSNumber alloc] initWithInt:arc4random()]];
    [data2 addObject:[[NSNumber alloc] initWithInt:arc4random()]];
}
double startTime = CACurrentMediaTime();
for(int i=0;i<1000;i++)
{
    NSArray *get1 = [all objectAtIndex:0];
    NSArray *get2 = [all objectAtIndex:1];
    //int get1Index = arc4random() % [get1 count];
    //int get2Index = arc4random() % [get2 count];

    //NSLog(@"Object at %d: %f", get1Index, [[get1 objectAtIndex:get1Index] doubleValue]);
    //NSLog(@"Object at %d: %f", get2Index, [[get2 objectAtIndex:get2Index] doubleValue]);
    NSLog(@"Object at %d: %f", i, [[get1 objectAtIndex:i] doubleValue]);
    NSLog(@"Object at %d: %f", i, [[get2 objectAtIndex:i] doubleValue]);
}
NSLog(@"Time with temp array:%f", CACurrentMediaTime() - startTime);

startTime = CACurrentMediaTime();
for(int i=0;i<1000;i++)
{
    //int get1Index = arc4random() % [[all objectAtIndex:0] count];
    //int get2Index = arc4random() % [[all objectAtIndex:1] count];

    //NSLog(@"Object at %d: %f", get1Index, [[[all objectAtIndex:0] objectAtIndex:get1Index] doubleValue]);
    //NSLog(@"Object at %d: %f", get2Index, [[[all objectAtIndex:1] objectAtIndex:get2Index] doubleValue]);
    NSLog(@"Object at %d: %f", i, [[[all objectAtIndex:0] objectAtIndex:i] doubleValue]);
    NSLog(@"Object at %d: %f", i, [[[all objectAtIndex:1] objectAtIndex:i] doubleValue]);
}
NSLog(@"Time without temp array:%f", CACurrentMediaTime() - startTime);
//With random access
//2012-01-28 13:44:12.721 test[23164:f803] Time with temp array:0.924193
//2012-01-28 13:44:13.641 test[23164:f803] Time without temp array:0.919250
//2012-01-28 13:44:44.892 test[23191:f803] Time with temp array:0.926337
//2012-01-28 13:44:45.812 test[23191:f803] Time without temp array:0.920447
//With incremental access
//2012-01-28 13:46:43.948 test[23231:f803] Time with temp array:0.935009
//2012-01-28 13:46:44.927 test[23231:f803] Time without temp array:0.978455
//2012-01-28 13:47:40.317 test[23254:f803] Time with temp array:1.173752
//2012-01-28 13:47:41.307 test[23254:f803] Time without temp array:0.989263

注释掉的部分是我用于测试随机访问的部分,对于我使用当前代码的增量访问。没有临时数组会更快,但不会明显。不足以牺牲可读性。我想这只是将它写入一个减慢变量的变量的过程,但同时,拥有一个未嵌入的临时数组要快得多。如果您多次使用嵌入式阵列,则必须进行2次内存访问,而不是1次。因此,如果您要多次使用嵌入式阵列,我认为增益将显着弥补使用临时阵列的损失。