const-correctness可以提高性能吗?

时间:2010-08-08 16:11:06

标签: c++ performance const-correctness

我已多次阅读过,在C或C ++代码中强制执行const正确性不仅是可维护性方面的一个好习惯,而且还可能允许编译器执行优化。但是,我也完全相反 - 它根本不会影响性能。

因此,您是否有一些示例,其中const正确性可以帮助您的编译器提高程序的性能?

4 个答案:

答案 0 :(得分:60)

const正确无法提高效果,因为const_castmutable在语言中,并且允许代码顺从地违反规则。这在C ++ 11中变得更糟,您的const数据可能会在例如是指向std::atomic的指针,这意味着编译器必须尊重其他线程所做的更改。

也就是说,编译器查看它生成的代码并确定它是否实际写入给定变量并相应地应用优化是微不足道的。

所有人都说,const正确性是可维护性的事物。否则,您班级的客户可能会破坏该班级的内部成员。例如,考虑标准std::string::c_str() - 如果它不能返回一个const值,你就可以使用字符串的内部缓冲区了!

出于性能原因,请勿使用const。出于可维护性原因使用它。

答案 1 :(得分:18)

是的,可以。

大多数const纯粹是为了程序员的利益而无法帮助编译器进行优化,因为抛弃它们是合法的,因此它们不会告诉编译器任何对优化有用的东西。但是,某些const不能(合法地)丢弃,这些确实为编译器提供了有用的优化信息。

作为示例,可以内联访问使用const类型定义的全局变量,而不能内联const类型的全局变量,因为它可能在运行时更改。

https://godbolt.org/g/UEX4NB

C ++:

int foo1 = 1;
const int foo2 = 2;

int get_foo1() {
    return foo1;
}

int get_foo2() {
    return foo2;
}

ASM:

foo1:
        .long   1
foo2:
        .long   2
get_foo1():
        push    rbp
        mov     rbp, rsp
        mov     eax, DWORD PTR foo1[rip] ; foo1 must be accessed by address
        pop     rbp
        ret
get_foo2():
        push    rbp
        mov     rbp, rsp
        mov     eax, 2 ; foo2 has been replaced with an immediate 2
        pop     rbp
        ret

实际上,请注意虽然const可以提高效果,但在大多数情况下,它不会或不会,但变化不会明显。 const的主要用途不是优化。

Steve Jessop在他对原始问题的评论中给出了另一个例子,它提出了一些值得一提的东西。在块作用域中,编译器可以推断出变量是否会被变异并相应地进行优化,而不管const,因为编译器可以看到变量的所有用法。相反,在上面的例子中,不可能预测foo1是否会被突变,因为它可以在其他翻译单元中修改。我想一个假设的有感知的超级编译器可以分析整个程序,并确定它是否有效内联访问foo1 ...但真正的编译器不能。

答案 2 :(得分:6)

根据我的经验,没有

对于标量变量,编译器能够确定何时更改值并自行执行必要的优化。

对于数组指针,const正确性并不能保证在存在潜在的别名问题时值实际上是常量。因此编译器不能单独使用const修饰符来执行优化

如果您正在寻找优化,则应考虑__restrict__或特殊功能修饰符/属性:http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html

答案 3 :(得分:5)