C ++:优化列表

时间:2014-07-22 12:32:09

标签: c++ arrays optimization stl

我的代码的一些密集分析显示,它花费了大量时间为向量分配空间 对于大多数这些向量,大小是事先已知的,因此我调用reserve()来预先分配空间 对于大多数这些矢量,尺寸几乎总是非常小 - 像4或5个元素,但在极少数情况下它可能非常大。
我想到的另一个优化是创建我自己的容器OptimizedList<T,N>。此对象的实例本身包含N个T实例作为普通数组,如果用户尝试添加超过N个项目,它将开始使用动态分配额外项目。

是否有已知的实现?

3 个答案:

答案 0 :(得分:1)

Qt&#39; stack based variable length array怎么样?

看起来像你的用例的完美匹配,大多是小数组,将在堆栈上分配(最快的分配,只是指针上的一对add / sub指令) 对于小型数组,在堆上用于大型数组。

然而,它确实浪费了空间。

答案 1 :(得分:1)

我会考虑将std::vector与针对4-5个元素优化的自定义分配器(从池中拉出来)作为最简单和最可行的解决方案。这也是我期望实际提供净收益的唯一解决方案。

使用std::deque可能没有帮助,尽管从教科书的角度来看似乎是这样。它实际上可能会受伤。 Deques减少了将数据从O(n)复制到O(1)的开销,但它们并没有神奇的分配。相反,与使用矢量相比,它们可能会产生更多的分配 Deques通常作为矢量矢量或循环缓冲器实现。在后一种情况下,您具有与使用std::vector 完全相同的重新分配开销,除非您无法通过调用reserve() 来缓解它,而在前一种情况下,您有两个分配,否则你只有一个。

将前几个对象直接嵌入到自定义矢量类中或嵌入到堆栈中的vararray中,就像在Bgie的答案中一样,这非常诱人,对于没有太多不太大的向量,这确实是一个很好的解决方案。
但是,由于您在创建这些向量时遇到了性能问题,因此可以得出结论,您不是仅使用5或10个向量,而是使用多个(否则它们并不重要,它不会不可测量!)。这意味着将数据放入堆栈可能会导致最终的堆栈溢出 然而,如果所有向量都是堆分配的,那么可能是一个很好的解决方案。在分配容器本身时是否多分配几百个字节没有什么区别,并且没有风险溢出堆栈。因此,在这种情况下,您可以有效地保存一个分配。

答案 2 :(得分:0)

由于您的大多数容器都很小而稀有容器有很多元素,所以我更喜欢std::deque。这可以帮助您避免以低价格进行不必要的重新分配。它没有reserve()方法,但由于大多数容器都很小,我认为没问题。

更重要,您应该检查这些容器中包含的对象类型。我认为瓶颈不是重新分配,而是复制/破坏它的一部分。我怀疑&#34;容器的价值观&#34;复制构造函数和/或析构函数是重的&#34;足够。复制N个元素然后在构造函数/析构函数过于复杂时销毁旧的N元素非常耗时。

作为上次优化,我建议使用内存池/分配器来减少底层的malloc / realloc / free调用。