Статические переменные и производительность в Objective-c - PullRequest
2 голосов
/ 28 января 2012

В приложении, которое имеет много различных UITableView, я часто использую временные массивы для импорта данных, используемых для заполнения табличного представления, определения количества строк, разделов, верхних и нижних колонтитулов и т. Д. Мне интересно, потому что эти массивы нужно создавать для каждой ячейки таблицы снова и снова, если объявление статики, чтобы их не нужно было создавать заново, будет способствовать повышению производительности, потому что сейчас эти массивы создаются в cellForRowAtIndexPath:, numberOfRowsInSections: , numberOfSectionsInTableView: , footerForSection: `. Может ли объявление о том, что такое большое количество статических массивов (которые могут содержать приличное количество информации, скажем, пару тысяч удвоений и пару сотен строк), в конечном счете, поможет мне или навредит мне? Я знаю, что статический массив остается в памяти на протяжении всей жизни приложения, поэтому будет ли это много статических массивов вредным? Предполагая, что этот процесс происходит в 4-5 контроллерах представления по всему приложению, мы говорим о 15-20 копиях этого массива, которые просто сидят без дела. Какой мой лучший вариант здесь? Спасибо

Edit: я использую синглтон, который содержит значения. Настоящая причина для временных массивов состоит в том, чтобы сохранить код в чистоте. Я могу сделать что-то вроде

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

тогда

* * 1010

вместо того, чтобы сгруппировать все в одно нечитаемое утверждение, например:

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

Я провел несколько собственных тестов, сравнивая время, необходимое для создания табличного представления с / без статической инициализации. Вот результаты:

2012-01-29 18:31:57.539 XXXXXXX[711:707] static average: 0.058798
2012-01-29 18:31:57.543 XXXXXXX[711:707] nonstatic average: 0.058395

Как видите, статическая инициализация на самом деле медленнее , чем нестатическая, но всего на несколько десятитысячных долей секунды. Вероятно, это просто результат неточных измерений, но результаты говорят достаточно, чтобы убедить меня, что разница достаточно мала, чтобы ее отклонить. Тайна раскрыта.

1 Ответ

3 голосов
/ 28 января 2012

Когда вы делаете вышеупомянутое, вы фактически не создаете новый массив, просто захватываете указатель на этот массив. Вы не копируете фактические данные.

Сохраняя ваш код в чистоте, вы теряете только производительность создания памяти для указателя и присвоения указателю значения. Так что нет, вы не теряете производительность.

Идея поддержания чистоты вашего кода гораздо важнее, чем это незначительное различие в дополнительном указателе здесь и там.


Edit:

Я провел некоторое тестирование между двумя, и, как и ожидалось, оба варианта работают очень похоже.

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. Поэтому, если вы собираетесь использовать встроенный массив несколько раз, я думаю, что выигрыш значительно компенсирует потерю использования временного массива.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...