Почти наверняка это зависит от значений old_size
, new_size
и header_size
, а также от реализации. Вам нужно будет выбрать некоторые значения и измерить.
1), вероятно, лучше всего в случае, когда header_size == old_size-1 && old_size == new_size-1
, так как это дает вам наилучшие шансы на то, что один realloc
в основном не работает. (2) в этом случае должен быть лишь немного медленнее (2 почти без операций немного медленнее, чем 1).
3), вероятно, лучше всего в случае, когда header_size == 1 && old_size == 1024*1024 && new_size == 2048*1024
, потому что realloc
пришлось бы переместить выделение, но вы избегаете копирования 1 МБ данных, которые вам не нужны. (2) в этом случае должно быть лишь немного медленнее.
2) лучше всего подходит, когда header_size
намного меньше, чем old_size
, а new_size
находится в диапазоне, при котором realloc
с достаточной вероятностью переместится, но также достаточно вероятно, что этого не произойдет. Тогда вы не можете предсказать, какой из (1) и (3) будет немного быстрее, чем (2).
При анализе (2) я предположил, что функция realloc вниз приблизительно свободна и возвращает тот же указатель. Это не гарантируется. Я могу думать о двух вещах, которые могут испортить вам жизнь:
- перераспределить копии вниз в новое распределение
- realloc вниз разделяет буфер, чтобы создать новый фрагмент свободной памяти, но затем, когда вы снова выполняете резервное копирование, распределитель не объединяет этот новый свободный фрагмент прямо обратно в ваш буфер, чтобы вернуться без копирование.
Любой из них может сделать (2) значительно дороже, чем (1). Таким образом, это деталь реализации, является ли (2) хорошим способом хеджирования ваших ставок между преимуществами (1) (иногда избегая копирования чего-либо) и преимуществами (3) (иногда избегая слишком большого копирования).
Кстати, такого рода праздные рассуждения о производительности более эффективны для предварительного объяснения ваших наблюдений, чем для предварительного предсказания того, какие наблюдения мы сделали бы в маловероятном случае, если бы мы действительно достаточно заботились о производительности, чтобы проверить ее.
Кроме того, я подозреваю, что для больших выделений реализация может выполнить даже перемещение realloc
без копирования чего-либо путем переназначения памяти на новый адрес. В этом случае они все будут быстрыми. Однако я не изучал, действительно ли реализации делают это.
person
Steve Jessop
schedule
06.11.2012
header_size
после перераспределения, поэтому мне все равно, что там. - person lqs   schedule 06.11.2012