const-correctness可以提高性能吗?

shu*_*alo 76 c++ performance const-correctness

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

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

Bil*_*eal 65

const正确性不能提高性能,因为const_castmutable所用的语言,并允许代码一致地打破规则.这在C++ 11中变得更糟,其中您的const数据可能是指向a的指针std::atomic,这意味着编译器必须尊重其他线程所做的更改.

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

这一切都表示,const正确性是一个很好的关于维修的事情.否则,您班级的客户可能会破坏该班级的内部成员.例如,考虑一下标准std::string::c_str()- 如果它不能返回一个const值,你就可以使用字符串的内部缓冲区了!

不要const出于性能原因使用.出于可维护性原因使用它.

  • "你可以用字符串的内部缓冲区搞定!" - 至关重要的是,你可以*意外*拧紧内部缓冲区.由于`const`引起的编译器错误是路标,说,"你做的事情很愚蠢". (28认同)
  • @Michael - 是的,公平点.也许最初的路标不是"你做的事情是愚蠢的",而是"某人做某事愚蠢". (7认同)
  • ...和const-casts是路标说,"这段代码的作者试图做一些聪明的事情";-) (4认同)
  • @Steve Jessop - 或const-cast是路标,说"我正在尝试将一组常量正确的代码连接到一个非常规正确的代码,我无法修复任何一个".我告诉你,这绝不是一件好事,只是讨厌. (4认同)

Pra*_*tic 23

是的,它可以.

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

例如,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;
}
Run Code Online (Sandbox Code Playgroud)

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
Run Code Online (Sandbox Code Playgroud)

实际上,请记住,虽然const可以提高性能,但在大多数情况下它不会或不会,但改变不会明显.主要用途const不是优化.


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


Any*_*orn 6

根据我的经验,没有

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

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

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