normal (nonplacement) new
в основном эквивалентно выполнению
T* ptr = static_cast<T*>(malloc(sizeof(T)));
new(ptr) T;
Конечно, реальность выглядит немного иначе из-за проверки ошибок и тому подобного, но результат болееили меньше того же самого (через не идентичный, вы не можете delete
указатель, выделенный таким образом, вместо этого вам нужно явно вызвать деструктор (ptr->~T()
) и затем освободить память, используя free
).
Таким образом, размещение new действительно должно быть быстрее, чем размещение без нового, так как не требуется выделять память.Однако проблема в том, что память должна быть где-то выделена.Таким образом, вы по существу заменили один вызов new
на вызов placement new
и некоторый код для выделения где-либо (если нет, то почему бы вы сначала использовали new
?).Должно быть очевидно, что это менее удобно и более подвержено ошибкам.
Теперь, конечно, вы можете написать более быстрый метод распределения, но для этого вам, как правило, нужно найти какой-то компромисс.Нелегко будет написать распределитель, который быстрее, без использования большего количества памяти (дополнительные данные для более быстрой идентификации свободных блоков) или без особой специфики (быстрое выделение одного размера объекта намного проще, чем обычного).В конце концов, это, как правило, не стоит усилий (для сценариев, где это стоит усилий, которые, вероятно, уже были сделаны, так что вы можете использовать существующий распределитель (который, вероятно, использует размещение внутри себя)).
Тамконечно, используются для размещения новых (иногда у вас есть предварительно выделенная память), но это просто не обычный случай