c++:优化列表
C++: Optimized list
对我的代码进行了一些深入的分析,发现它花了很多时间为向量分配空间。
对于大多数这些向量的大小是事先已知的,所以我调用reserve()
来预先分配空间。对于大多数这些向量,大小几乎总是非常小-像4或5个元素,但在极少数情况下,它可以相当大。我想到的另一个优化是创建我自己的容器OptimizedList<T,N>
。这个对象的一个实例本身包含N个T的实例,作为一个普通数组,如果用户试图添加超过N个项目,它将开始为额外的项目使用动态分配。
是否有已知的实现?
如何Qt的堆栈为基础的可变长度数组?
看起来与您的用例完美匹配,主要是小数组,将在堆栈上分配(最快的分配,只是一对指针上的add/sub指令)对于小数组,在堆上对于大数组。
我会考虑使用std::vector
与自定义分配器优化4-5个元素(从池中提取)作为最简单和最可行的解决方案。这也是唯一的解决方案,我希望实际提供净收益。
使用std::deque
可能没有帮助,尽管从教科书的角度来看似乎是这样。它可能真的很疼。deque减少了将数据从O(n)复制到O(1)的开销,但它们并不是神奇的无分配。相反,与使用vector相比,它们可能会导致更多的分配。
deque通常以向量的向量或循环缓冲区的形式实现。在后一种情况下,除了不能通过调用reserve()
来减轻它之外,您有与使用std::vector
完全相同的重新分配开销,并且在前一种情况下,您有两个分配,否则您只有一个。
将前几个对象直接嵌入到自定义向量类中,或者像Bgie的答案那样嵌入到堆栈上的变量数组中,这是非常诱人的,这确实是一个不太多不太大的向量的很好的解决方案。
然而,由于创建这些向量会产生性能问题,因此可以得出结论,您使用的不是5个或10个向量,而是许多个向量(否则就不重要了,它就无法测量!)。这意味着将数据放在堆栈上可能最终导致堆栈溢出。
然而,如果所有向量都是堆分配的,那么可能是一个很好的解决方案。在分配容器本身时,是否再分配几百字节并没有真正的区别,也没有溢出堆栈的风险。在这种情况下,你可以有效地节省一次分配。
因为你的大多数容器都很小,稀有的容器得到许多元素,我更喜欢std::deque
。这可以帮助您以较低的价格避免不必要的重新分配。它没有reserve()
方法,但由于大多数容器都很小,我认为它可以。
更重要的是,您应该检查包含在这些容器中的对象类型。我认为瓶颈不是重新分配本身,而是复制/破坏它的一部分。我怀疑"容器的值"复制构造函数和/或析构函数足够"重"。当构造函数/析构函数太复杂时,复制N个元素然后销毁旧的N个元素非常耗时。
作为最后的优化,我建议使用内存池/分配器来减少底层的malloc/realloc/free调用。
- 空基优化子对象的地址
- Pybind11:将元组列表从Python传递到C++
- 从链接列表c++中删除一个项目
- 如何(从固定列表中)选择一个数字序列,该序列将与目标数字相加
- C++如何通过用户输入删除列表元素
- 读取文件的最后一行并输入到链接列表时出错
- 复制列表初始化的隐式转换的等级是多少
- LNK2038、MSVS2017 MAGMA的原因列表
- 不能在初始值设定项列表中将非常量表达式从类型 'int' 缩小到'unsigned long long'
- 没有为自己的结构调用列表推回方法
- 使用简单类型列表实现的指数编译时间.为什么
- 关闭||运算符优化
- 一对向量构造函数:初始值设定项列表与显式构造
- 如何优化代码以返回最接近给定整数的数字,但给定列表中不存在?
- 如何告诉 gcc 显示您使用的优化标志列表
- GCC缺少优化CTOR初始化器列表的机会
- 如何从路径列表中优化目录列表
- OpenGL 显示列表优化
- 由于构造函数初始值设定项列表而优化
- c++:优化列表