如果可能,标准::映射分配是否静态
Is std::map allocation static when possible?
考虑具有相同效果的 3 个版本的代码:
版本1:
int main() {
std::map<int,int> x = {{0,0}, {1,1}, {2,2}};
// Do some stuff...
return 0;
}
版本2:
int main() {
std::map<int,int> x;
x[0] = 0;
x[1] = 1;
x[2] = 2;
// Do some stuff...
return 0;
}
版本3:
int main() {
std::map<int,int> x;
x.insert(std::pair<int,int>(0,0));
x.insert(std::pair<int,int>(1,1));
x.insert(std::pair<int,int>(2,2));
// Do some stuff...
return 0;
}
这些代码的效率如何?
我认为版本 1 是完全静态的分配:x
所需的空间分配一次并设置值。我还认为版本 3 需要动态分配:每次调用插入都会检查键是否尚未使用,检查插入位置并在分配值之前分配更多空间进行映射。对于版本 2,我不确定。你能帮我吗?
C++标准对分配是在编译时还是运行时进行没有要求。所有这些都意味着实现可以自由地进行自己的优化(或不进行(。
因此,正确的做法是进行测试。
很可能尚未实施此类优化。没有std::map
的constexpr
构造函数,尽管您在此处创建的std::initializer_list
可能是编译时常量(请注意,这里也没有执行聚合初始化(
std::map<int,int> x = {{0,0}, {1,1}, {2,2}};
虽然它的实现是定义的,但std::map
的分配从来都不是静态的。它使用 RB 树作为100例中99例的底层数据结构。
在您的情况下,在所有三种情况下,您具有完全相同的时间和空间复杂性。
经过所有这些猜测,我终于分析了代码。为此,我生成了 3 个代码,就像问题中一样,但有 100,000 个条目。以下是使用g++编译的多次运行平均值的结果,没有优化:
- 版本 1:26 毫秒(编译时间:2.5 秒(
- 版本 2:80 毫秒(编译时间:10 秒(
- 版本 3:73 毫秒(编译时间:37 秒(
很明显,最好的解决方案是第一个。版本 2 和 3 在执行时几乎是等效的,但版本 3 在编译时确实更糟。
相关文章:
- 拥有映射的现代方法,该映射可以指向或引用已在堆栈上分配的不同类型的数据
- C++ 将元素分配给映射值时访问错误
- 包含动态分配内存作为值的映射的取消定位速度有多快?
- 如果可能,标准::映射分配是否静态
- 如何在 OpenCL 中使用缓冲区分配和映射内存机制
- 我如何正确地为std ::映射分配内存
- 我如何将输入分配给在 for 循环中设置的映射功能
- 映射和设置总是一次分配一个项目吗
- 静态映射中动态分配的对象.删除必要的
- C++:通过从映射向量分配映射实例来填充映射的映射
- 映射中的分配最终为0
- C 索引中的字符串映射而无需分配
- 循环访问映射并删除动态分配的元素
- 将无序映射与动态分配的用户定义类一起使用
- STL映射是如何分配的?堆叠或堆
- 任何查找分配给映射的内存大小的方法
- 两个映射之间的分配-移动语义和性能
- c++动态分配(像素映射)
- 标准::移动和映射分配
- C++ std::映射分配错误:无法在赋值中将' type **'转换为'type *'