Это медленно, чтобы сделать много mallocs и освобождает на iPhone? - PullRequest
2 голосов
/ 14 сентября 2010

У меня есть массив точечных данных (для частиц), который постоянно меняет размер. Чтобы приспособиться к изменяющемуся размеру, я использую код, подобный следующему, для создания буферов правильного размера с частотой около 60 Гц.

 free(points);
 points = malloc(sizeof(point3D) * pointCount);

Это приемлемо или есть другой способ сделать это? Может ли это привести к замедлению работы моего приложения или к перебоям памяти? Когда я запускаю его под инструментами в симуляторе, он не выглядит особенно плохо, но я знаю, что симулятор отличается от устройства.

РЕДАКТИРОВАТЬ: На момент написания, нельзя было протестировать на устройстве без лицензии разработчика. У меня не было лицензии и я не смог профилировать на устройстве.

Ответы [ 6 ]

3 голосов
/ 14 сентября 2010

Распределение памяти быстро по отношению к некоторым вещам и медленно по сравнению с другими.Средняя программа Objective-C делает намного больше, чем 60 распределений в секунду.При выделении нескольких миллионов байтов malloc + free должно занимать менее тысячи секунд .По сравнению с арифметическими операциями это медленно.Но по сравнению с другими вещами это быстро.

Достаточно ли быстро в вашем случае - это вопрос для тестирования.Конечно, на iPhone можно выделить 60 Гц памяти - процессор работает на частоте 600 МГц.

Хотя это, безусловно, хороший вариант для повторного использования памяти.Следите за размером пула и выделяйте больше, если вам нужно больше.Не выделять память всегда быстрее, чем выделять ее.

3 голосов
/ 14 сентября 2010

Попробуйте начать с подсчитанного количества частиц и malloc - с массивом такого размера. Затем, если вам нужно увеличить количество частиц, используйте realloc, чтобы изменить размер существующего буфера. Таким образом, вы минимизируете количество выполняемых операций выделения / освобождения.

Если вы хотите убедиться, что не тратите память, вы также можете вести учет последних 100 (или около того) количеств частиц. Если максимальное количество частиц из этого набора меньше (скажем, 75% от вашего текущего размера буфера), измените размер буфера, чтобы соответствовать меньшему количеству частиц.

1 голос
/ 14 сентября 2010

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

У меня есть приложения для iPhone, которые выполняют много тысяч malloc и освобождаются в секунду, и они даже не отображаются впрофиль приложения.

Таким образом, ответ на оригинальный вопрос - нет.

1 голос
/ 14 сентября 2010

Как уже упоминалось в hotpaw2, если вам нужно оптимизировать, вы, возможно, можете сделать это, только выделяя, если вам нужно больше места, например:

particleCount = [particles count];
if (particleCount > allocatedParticleCount) {
  if (vertices) {
    free(vertices);
  }
  if (textures) {
    free(textures);
  }
  vertices = malloc(sizeof(point3D) * 4 * particleCount);
  textures = malloc(sizeof(point2D) * 4 * particleCount);
  allocatedParticleCount = particleCount;
}

... инициализируя allocParticleCount в 0 при создании экземпляра вашего объекта.

PS Не забудьте освободить ваши объекты, когда ваш объект уничтожен.Рассмотрите возможность использования файла .mm и используйте C ++ / Boost's shared_array как для вершин, так и для текстур.Тогда вам также не потребуются вышеуказанные бесплатные заявления.

1 голос
/ 14 сентября 2010

Вам не нужно повторно размещать, пока количество частиц не увеличится (или пока вы не обработали предупреждение памяти).Просто оставьте для сравнения последний размер malloc.

0 голосов
/ 14 сентября 2010

В этом случае вы, вероятно, захотите сохранить эту память и просто переназначить ее.

...