我正在编写一个内部循环,需要将 struct
s 放在连续存储中。我不知道其中有多少 struct
会提前。我的问题是 STL 的 vector
将其值初始化为 0,所以无论我做什么,我都会承担初始化成本以及将 struct
的成员设置为价值观。
有什么方法可以阻止初始化,还是有一个类似 STL 的容器,具有可调整大小的连续存储和未初始化的元素?
(我确信这部分代码需要优化,而且我确信初始化是一笔不小的开销。)
另外,请参阅下面的评论以了解初始化发生的时间。
一些代码:
void GetsCalledALot(int* data1, int* data2, int count) {
int mvSize = memberVector.size()
memberVector.resize(mvSize + count); // causes 0-initialization
for (int i = 0; i < count; ++i) {
memberVector[mvSize + i].d1 = data1[i];
memberVector[mvSize + i].d2 = data2[i];
}
}
原文由 Jim Hunziker 发布,翻译遵循 CC BY-SA 4.0 许可协议
std::vector
必须以某种方式初始化数组中的值,这意味着必须调用一些构造函数(或复制构造函数)。vector
(或任何容器类)的行为是未定义的,如果您要访问数组的未初始化部分,就像它已初始化一样。最好的方法是使用
reserve()
和push_back()
,以便使用复制构造函数,避免默认构造。使用您的示例代码:
像这样调用
reserve()
(或resize()
)的唯一问题是,您最终可能会比您需要的更频繁地调用复制构造函数。如果你可以对数组的最终大小做出一个很好的预测,最好在开头reserve()
空格。但是,如果您不知道最终大小,则至少平均副本数会最少。在当前版本的 C++ 中,内部循环有点低效,因为临时值在堆栈上构造,复制构造到向量内存,最后临时值被销毁。然而,下一版本的 C++ 有一个称为 R 值引用 (
T&&
) 的功能,这将有所帮助。std::vector
提供的接口不允许其他选项,即使用一些类似工厂的类来构造默认值以外的值。下面是这个模式在 C++ 中实现的粗略示例:这样做确实意味着您必须创建自己的矢量类。在这种情况下,它也使本来应该是一个简单的例子变得复杂。但是有时使用这样的工厂函数可能会更好,例如,如果插入是以其他值为条件的,那么即使实际上不需要,您也必须无条件地构造一些昂贵的临时函数。