考虑具有相同效果的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需要动态分配:每次调用insert都会检查密钥是否尚未使用,检查插入位置并在分配值之前分配更多空间进行映射。
对于版本2,我不确定。你能帮帮我吗?
答案 0 :(得分:4)
C ++标准对于在编译时或运行时是否发生分配没有要求。所有这些意味着实现可以自由地进行优化(或不是)。
所以要做的就是测试。
这种优化很可能尚未实施。尽管您在此处创建的constexpr
可能是编译时常量(请注意,此处未执行聚合初始化),但std::map
没有std::initializer_list
构造函数。 p>
std::map<int,int> x = {{0,0}, {1,1}, {2,2}};
答案 1 :(得分:2)
虽然定义了它的实现,但std::map
的分配永远不会是静态的。它使用RB tree
作为99个案例中的基础数据结构
在您的情况下,在所有三种情况下,您具有完全相同的时间和空间复杂性。
答案 2 :(得分:1)
在所有这些推测之后,我终于分析了代码。为此,我在问题中生成了3个代码,但有100,000个条目。以下是几次运行的平均结果,使用g ++编译而没有优化:
很明显,最好的解决方案是第一个。版本2和版本3在执行时几乎相同,但版本3在编译时确实更差。