Вопрос по performance, key-value-coding, cocoa, key-value-observing, data-structures – Падение производительности при использовании NSMutableDictionary и NSMutableArray>

4

Я рассматриваю возможность использования NSMutableDictionary вместо моего текущего NSMutableArray. Это в первую очередь по причинам KVC / KVO. Коллекция подвергнется сильной мутации во внутренней петле моего метода рисования. Могу ли я ожидать значительного снижения производительности, если я продолжу эту замену?

Ура, Doug

Ваш Ответ

3   ответа
0

Когда вы говорите «в основном по причинам KVC / KVO», можете ли вы уточнить?

Если вы видите проблемы с производительностью из-за чрезмерного запуска KVO при сильной мутации, рассмотрите возможность запуска уведомлений KVO самостоятельно, как только вы закончите:

[self willChangeValueForKey: @"myArray"];

// loop and mutate

[self didChangeValueForKey: @"myArray"];
Привет, Фрейзер, я делаю приложение для iPhone с системой частиц, с сотнями спрайтов, бродящих по экрану. Рендеринг выполняется в OpenGL. Для ухмылок я использовал KVO для каждой частицы, чтобы наблюдать их рождение / смерть и приложение остановилось, когда я установил его на устройство. Проблема словаря / массива не актуальна, поскольку накладные расходы KVO в этом случае непомерно высоки. dugla
4

нужно проверить эти вещи. Но ... следующий простой тест был для меня поучительным, чтобы получить представление об относительной разнице в скорости между классами коллекций NSMutableDictionary и NSMutableArray в случае небольших размеров с высокой скоростью выделения.

При запуске следующей программы время было: (с включенной сборкой мусора) (на недавнем четырехъядерном компьютере)

NSMutableDictionary 4.624478 секунд NSMutableArray 1.806365 секунд

int main (int argc, const char * argv[])
{
    NSLog(@"Hello, World!");

    LNCStopwatch* stopwatch = [[LNCStopwatch alloc] init];
    [stopwatch start];
    for (int i = 1; i< 1000000; i++)
    {
        NSMutableDictionary* dict = [[NSMutableDictionary alloc]init];
        [dict setObject:@"a" forKey:@"a"];
        [dict setObject:@"b" forKey:@"b"];
        [dict setObject:@"c" forKey:@"c"];
        [dict setObject:@"d" forKey:@"d"];
        [dict setObject:@"e" forKey:@"e"];
        [dict setObject:@"y" forKey:@"a"];
        [dict setObject:@"x" forKey:@"d"];
    }
    [stopwatch stopAndLogTimeAndReset];
    [stopwatch start];
    for (int i = 1; i< 1000000; i++)
    {
        NSMutableArray* arr = [[NSMutableArray alloc]init];
        [arr addObject:@"a"];
        [arr addObject:@"b"];
        [arr addObject:@"c"];
        [arr addObject:@"d"];
        [arr addObject:@"e"];
        [arr replaceObjectAtIndex:[arr indexOfObject:@"a"] withObject:@"y"];
        [arr replaceObjectAtIndex:[arr indexOfObject:@"d"] withObject:@"x"];
    }
    [stopwatch stopAndLogTimeAndReset];

    return 0;
}

(Абсолютные времена, которые я не считаю действительно важными, это просто относительные времена, которые более важны для этих классов малого размера. Конечно, для классов большего размера природа класса коллекции будет доминировать, например, NSMutableDictionary должен быть O (1) найти элемент и т.д ...)

6

Единственный способ убедиться - это измерить. Ни у кого из нас нет достаточных знаний о том, как работают реализации NSMutableDictionary и NSMutableArray, так что тут нет смысла спрашивать.

Конечно, вы можете ожидать некоторого попадания, так как словарь должен выполнять дополнительное хеширование, чего не делает простой массив. Является ли это "значительным" или нет? Сложно сказать.

Снова,measure.

Похожие вопросы