看来, placement new
在预分配的内存上创建一个新对象,这是否意味着它需要更少的时间?看起来它比使用旧普通分配更快 new
。然后,如果这样方便快捷,为什么不使用 placement new
每时每刻?
看来, placement new
在预分配的内存上创建一个新对象,这是否意味着它需要更少的时间?看起来它比使用旧普通分配更快 new
。然后,如果这样方便快捷,为什么不使用 placement new
每时每刻?
该 正常 (nonplacement) new
基本上相当于做
T* ptr = static_cast<T*>(malloc(sizeof(T)));
new(ptr) T;
当然,由于错误检查等现实看起来有点不同,但结果或多或少相同(通过不相同,你不能 delete
一个指针分配的方式,而你需要明确地调用析构函数(ptr->~T()
)然后使用释放内存 free
)。
因此,放置new应该比非放置new更快,因为它不需要分配内存。但问题是需要在某处分配内存。所以你基本上已经取代了一个电话 new
打电话给 placement new
以及某些地方的分配代码(如果不是为什么你会使用 new
首先?)。很明显,这不太方便,更容易出错。
当然,你现在可以写一个更快的分配方法,但为此你通常需要做一些权衡。编写一个分配器并不容易,如果没有使用更多的内存(额外的数据可以更快地识别空闲块)或使其非常具体(编写单个对象的快速分配比一般的更容易)。最后,通常不值得付出努力(对于可能已经完成的努力值得花钱的情况,所以你可以使用现有的分配器(可能在内部使用placement new))。
当然有用于放置新的(有时你确实预先分配了内存),但这不是常见的情况
对于大多数程序来说,这是不必要的,因为它们的使用模式不需要它。对于那些不使用堆的程序来说没有区别,并且很难做到正确(比你的操作系统更好)。您也可以通过优化分配获得如此多的收益。在大多数情况下,任何算法优化都将导致更大的总体加速。通常不需要定制分配器可以提供的许多保证(通过预分配的内存分配的保证时间限制,低内存碎片)。
肯定有程序可以从内存管理中受益,它们很难识别。在您发现内存分配实际上是瓶颈之后,找到更好的分配方案就更难了。当一切都完成后,仍然不值得麻烦。
放置new的目的之一是使用自定义分配器来创建新对象,并调用它们的构造函数。它并不总是更快,因为它只能与您的自定义分配器一样快。
用于将对象放置在内存中特定位置的新位置可能需要较少的时间,因为您实际上避免分配内存 在这一步。
但是,它必须在某个时刻分配,之前可能需要时间。 如果你真的有理由将对象放在预分配的内存中,那么使用它是有意义的。
这不是一次性使用 新 运营商。更多细节 这里。
另外,请记住,placement new不会自动调用析构函数!
你必须做 foo->~Foo();
为您 Foo foo;
手动。
我发现放置new的唯一地方会使你的分配速度明显加快,如果你有大量相同大小的对象,它们的生命周期有限,导致它们经常被分配和销毁。如果您不能保证这种行为,那么最好使用默认的新实现。
需要大量相同大小对象的应用程序通常可以从池(或批量)分配中看到主要的加速。基本上,您为该对象的大量分配一个大缓冲区(或页面),然后在请求该对象时调用其中的placement new。虽然这可以加快速度,但对大多数程序来说并不是必需的。
尝试为不需要它的程序执行此操作可能只会给您一个最小的加速,但可能会花费您大量的调试时间。
所以真的看看你需要什么;如果您要分配大量相同的对象,是的,新位置可能会更快。但只是几个对象?我不打扰。
但是,这并不总是一个时间问题。例如,您可以使用placement new来保证对象在堆上的对齐。你可以这样做:
void* buffer = aligned_malloc(sizeof(Object), 16);
Object* object = new (buffer) Waypoint();
这对于某些类型是必要的,例如浮点数组与SSE函数和寄存器一起使用。