Почему new()/delete() работает медленнее, чем malloc()/free()?
EDIT:
Спасибо за ответы до сих пор. Пожалуйста, укажите спецификации стандартной реализации С++ new() и delete(), если у вас есть спасибо!
Почему new()/delete() работает медленнее, чем malloc()/free()?
Спасибо за ответы до сих пор. Пожалуйста, укажите спецификации стандартной реализации С++ new() и delete(), если у вас есть спасибо!
Посмотрите на этот фрагмент кода 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()
.)
new и delete имеют дело со строительством/уничтожением, для которых частью их работы являются эффективные вызовы malloc() и free() - malloc() и free() - это распределение/освобождение памяти.
Если вы используете их для распределения "простых старых данных", так что конструктор/деструктор тривиальны, они вряд ли сильно различаются по скорости от malloc
/free
. Возможно (вероятно?), Что вы допустили ошибку где-то в ваших измерениях, что привело к искажению результатов. На самом деле все, что они делают, кроме вызова malloc
/free
, это конструктор/деструктор выполнения (несколько раз для массивов).
Когда вызывается new
оператор, происходят две вещи:
Таким образом, из-за накладных расходов на строительство объектов, new
медленнее, чем malloc
.
Аналогично, delete
выполняет две вещи:
Короче говоря, malloc
выделяет только необработанную память, тогда как new
не только выделяет необработанную память, но и превращает необработанную память в объекты.
Их не должно быть, и их нет в кодовой базе, в которой я работаю.
Там, где я работаю, malloc/free работает медленнее и более неэффективно, чем new/delete по двум причинам: