В дополнение к тому, что было сказано ранее, необходимо учесть еще несколько моментов:
Производительность realloc(<X-sized-buf>, X + inc)
зависит от двух вещей:
- скорость
malloc(N + inc)
который обычно уменьшается до O(N)
с размером выделенного блока - со скоростью
memcpy(newbuf, oldbuf, N)
, которая также O(N)
с размером блока
Это означает, что для небольшие приращения, но большие существующие блоки, производительность realloc()
составляет O(N^2)
по отношению к размеру существующего блока данных.Подумайте, пузырьковая сортировка против быстрой сортировки ...
Это сравнительно дешево, если вы начнете с небольшого блока, но значительно накажет вас, если блок, который будет перераспределен, большой.Чтобы смягчить, вы должны убедиться, что inc
равно не мало относительно существующего размера;Перераспределение на постоянную величину - это рецепт проблем с производительностью.
Кроме того, даже если вы увеличиваете с большим шагом (скажем, масштабируйте новый размер до 150% от старого), есть скачок использования памяти от перераспределения большого буфера;во время копирования существующего содержимого вы используете вдвое больше памяти.Последовательность:
addr = malloc(N);
addr = realloc(addr, N + inc);
поэтому терпит неудачу (намного) раньше, чем:
addr[0] = malloc(N);
addr[1] = malloc(inc);
Существуют структуры данных, которым не требуется realloc()
для роста;связанные списки, списки пропусков, деревья интервалов - все они могут добавлять данные без необходимости копировать существующих данных.C ++ vector<>
растет таким образом, он начинается с массива для начального размера и продолжает , добавляя , если вы его увеличите, но он не будет realloc()
(т.е. копировать).Попробуйте реализовать (или использовать уже существующую реализацию) нечто подобное.