堆栈或堆栈数组。用户定义的类型难题

时间:2014-03-28 22:58:29

标签: c++ arrays memory

更新

  • 重写了这个问题,以便更好地适应我想要提出的问题。

当设计一个大小不足的容器时,该容器不够大,不足以保证堆分配但是不够小,移动语义不会产生任何差别。如何确定设计容器的方式以使其具有高性能(尺寸/空间是次要的)。

据我所知,有两种方法:

方法(A)将内部数据实现为指针并使用堆分配。 T* data = new T[]

方法(B)实现堆栈数组数据结构。 T data[]

我是C ++的新手,并且已经阅读了很多有关堆栈与堆的文章。这就是我目前收集的......

方法(A)

的优点:

  • 在需要之前没有完整的结构/类内存分配(可以在空构造函数上使用nullptr,直到初始化/分配),尽管指针仍然需要32位/ 64位。
  • 可以使移动可构造并移动可分配。

缺点:

  • 必须为每个对象分配(除非使用堆内存池)

方法(B)

的优点:

  • 堆栈内存比堆快(因为获取堆栈内存只涉及在满足的环境中移动堆栈点与堆分配以查找连续块。)
  • 更有可能出现在处理器缓存中,因为内存位置适用于热点"数据。

缺点:

  • 无法移动
  • 必须立即在声明的位置分配内存。

例如,如果给定用户设计的类型将用于进行大量计算,这意味着很多临时工。什么是最高效的方式?

堆数组的移动能力,当与nullptr结合使用时,能够进行零拷贝在我看来它会消除堆栈给出的任何优势,因为移动仅涉及1个指针替换与介质大小的数组副本。

是否有我错过或误解的因素?通常需要知道什么才能决定采用哪种方法?

堆栈是否可以比堆移动/指针重新分配更快地复制数据数组?

1 个答案:

答案 0 :(得分:2)

如果您不确定是否需要,则不应动态分配。除了速度和空间的影响之外,它只需要更多的代码来编写和正确。此外,如果某些客户端代码需要间接(例如,为了有效地移动,或通过省略数据来节省空间),他们总是可以从外部添加:std::unique_ptr<ModeratelyLargeType>正常工作。

关于特定的int24类型:

你应该把它变成一个包含三个uint8_t的结构或一些直接将24位直接输入对象的方法。我认为你的意思是“堆栈数组”。方法A的“优点”和你列出的方法B的相应“缺点”是无稽之谈:

  

[A +]在需要之前没有内存分配(可以在空构造函数上使用nullptr,直到初始化/分配)

     

[B - ]必须立即在声明的位置分配内存。

方法A总是需要分配指针,指针大于实际数据(32位或64位对24位)。方法A不仅实际使用时使用的内存超过两倍,即使不使用它也会占用更多内存。所有这些都没有考虑堆分配器元数据的空间开销。

为了完整性我应该添加,取决于你如何实现它,对齐可能会强制编译器插入填充,使结构大于24位但仍然不大于空指针(所以上面仍然站立)。同样,它显然不会使用32位寄存器的四分之三。

  

[A +]可以使移动可构造并移动可分配。

     

[B - ]无法移动?

好吧,你可以移动指针,但这并不比复制三个字节更有效。同样,指针大于它指向的数据。