我知道使用C 11编译器而不是C 03编译器编译时可以提高性能(请参阅此问题)。
但是,从C 11编译器到C 14编译器时,我可以期待性能提升吗?
如果是这样,您能否向我展示一个代码示例,当使用C 14而不是C 11编译时,它会更快。
C 14中的核心语言更改允许实现合并内存分配,请参阅N3664。如果您的编译器/优化器利用此许可,您可能会看到性能改进。
解决了所有缺陷的完全兼容的C 14编译器至少有一位代码被要求比C 11版本更高效。
struct one_byte { char x = 7; };
struct cheap_move {
std::vector<one_byte> state{1000000}; // 1 mb of state, cheap to move
};
struct test_type {
test_type(test_type const&)=default;
test_type(test_type &&)=default;
// can construct from a cheap_move via either copy or move:
test_type(cheap_move const&y):x(y){}
test_type(cheap_move &&y):x(std::move(y)){}
cheap_move x;
};
test_type test_func() {
cheap_move m;
return m;
}
返回m;兼容C 11的编译器中的
将复制1兆字节的内存。在实现了缺陷1579的C 14编译器中,它将复制3个指针(好吧,移动1个向量)。
这是因为在C 11中,隐式转换为右值只有在类型完全匹配时才会发生。在上述缺陷报告(列为C 14)下,如果有一个使用右值的构造函数匹配,则会发生这种情况。所以C 14移动到返回值中,而C 11复制到返回值中。
(@T. C.追踪了上面的缺陷报告)。
请注意,并非所有C 14编译器都实现了对该缺陷的修复。此时http://coliru.stacked-crooked.com/的clang和gcc都没有在C 14或C 1z模式下实现对该缺陷的修复。
一个不那么做作的例子是:
struct modulate {
std::vector<double> state;
double operator()(double x)const{
double r = 0;
for (double v:state) {
r*=x;
r+=v;
}
return r;
}
};
std::function< double(double) > f( std::vector<double> state ) {
auto m = modulate{std::move(state)};
return m;
}
返回在C 14中隐式移动,并在C 11中复制。
请注意,一个简单的std::移动(m)
会使C 11做与C 14相同的事情,但是“你不移动
返回局部变量”的规则会导致人们避免这种情况(因为它会阻止省略):考虑到一般规则,这种“错误”是常见的。
在C 11中,这种“错误”导致上述效率低下,但在C 14中不再是错误。
不是天生的。
随着时间的推移,编译器在代码生成方面变得更好,您可能会期望性能通常会提高,因此较新的编译器通常会被认为“更好”,并且比旧的编译器更有可能擅长优化。
但是您会通过在C 11和C 14模式之间切换自动获得更快的程序吗?没有。