Подтвердить что ты не робот

Почему new()/delete() медленнее, чем malloc()/free()?

Почему new()/delete() работает медленнее, чем malloc()/free()?

EDIT:

Спасибо за ответы до сих пор. Пожалуйста, укажите спецификации стандартной реализации С++ new() и delete(), если у вас есть спасибо!

4b9b3361

Ответ 1

Посмотрите на этот фрагмент кода C:

struct data* pd = malloc(sizeof(struct data));
init_data(pd);

Оператор new в С++ по существу выполняет то, что делает вышеприведенный фрагмент кода. Поэтому он медленнее, чем malloc().

Аналогично с delete. Это делает эквивалент этого:

deinit_data(pd);
free(pd);

Если конструкторы и деструкторы пустые (например, для встроенных), new и delete не должны быть медленнее, чем malloc() и free(). (Если это так, часто из-за того, что общие реализации вызывают malloc()/free() под капотом, поэтому они являются оберткой вокруг них. Стоимость упаковки. Также может быть код, который должен выяснить, что нет конструкторы/деструкторы, которые тоже будут стоить.)

Изменить. Чтобы ответить на ваш дополнительный вопрос:

new и delete не являются функциями, они являются операторами. Это: new data() называется новым выражением. Это делает две вещи. Сначала он вызывает operator new, затем инициализирует объект, обычно, вызывая соответствующий конструктор. (Я говорю "обычно", потому что встроенные объекты не имеют конструкторов. Но новое выражение, включающее встроенный, работает тем же.)

Вы можете управлять обеими этими фазами. Вы можете создавать свои собственные конструкторы для управления инициализацией ваших типов, и вы можете перегружать operator new (даже при нескольких перегрузках, имеющих разные дополнительные аргументы, а также специально для каждого класса, если хотите), чтобы управлять распределением свободного хранилища. Если вы не реализуете свой собственный operator new, используется версия из стандартной библиотеки. Обычная реализация этого вызова malloc().

Аналогично, если вы пишете delete pd, называете выражение delete, происходят две вещи: в зависимости от pd объект де инициализируется, обычно, вызывая его деструктор, затем память освобождается, вызывая соответствующий operator delete.

Опять же, вы можете манипулировать обеими фазами, написав свой собственный деструктор и написав собственную версию operator delete. (Версия operator delete, которая поставляется с вашей стандартной библиотекой, часто реализуется для вызова free().)

Ответ 2

new и delete имеют дело со строительством/уничтожением, для которых частью их работы являются эффективные вызовы malloc() и free() - malloc() и free() - это распределение/освобождение памяти.

Ответ 3

Если вы используете их для распределения "простых старых данных", так что конструктор/деструктор тривиальны, они вряд ли сильно различаются по скорости от malloc/free. Возможно (вероятно?), Что вы допустили ошибку где-то в ваших измерениях, что привело к искажению результатов. На самом деле все, что они делают, кроме вызова malloc/free, это конструктор/деструктор выполнения (несколько раз для массивов).

Ответ 4

Когда вызывается new оператор, происходят две вещи:

  1. Память выделяется для объекта в куче.
  2. Конструктор объекта вызывается.

Таким образом, из-за накладных расходов на строительство объектов, new медленнее, чем malloc.

Аналогично, delete выполняет две вещи:

  1. Вызывает деструктор кучи объекта.
  2. Распределяет память объекта.

Короче говоря, malloc выделяет только необработанную память, тогда как new не только выделяет необработанную память, но и превращает необработанную память в объекты.

Ответ 5

Их не должно быть, и их нет в кодовой базе, в которой я работаю.

Там, где я работаю, malloc/free работает медленнее и более неэффективно, чем new/delete по двум причинам:

  • free() не знает размер объекта, тогда как delete часто имеет этот размер во время компиляции.
  • Функция malloc() не знает тип объекта, который она выделяет, поэтому она всегда должна предоставлять памяти 16-байтовое выравнивание. Это часто может быть расточительным.