【发布时间】:2014-01-21 00:34:51
【问题描述】:
Consexpr 对于编译优化非常有用。比如……
strlen(char*)
可以使用....进行预编译
constexpr inline size_t strlen_constexpr(char* baseChar) {
return (
( baseChar[0] == 0 )
?(// if {
0
)// }
:(// else {
strlen_constexpr( baseChar+1 ) + 1
)// }
);
}
优化后它的运行时成本为 "0"...但运行时慢了 10+x 以上
// Test results ran on a 2010 macbook air
--------- strlen ---------
Time took for 100,000 runs:1054us.
Avg Time took for 1 run: 0.01054us.
--------- strlen_constexpr ---------
Time took for 100,000 runs:19098us.
Avg Time took for 1 run: 0.19098us.
是否有任何现有的宏/模板黑客可以使用单个统一功能来代替。即。
constexpr size_t strlen_smart(char* baseChar) {
#if constexpr
... constexpr function
#else its runtime
... runtime function
}
或一些允许以下内容的重载黑客
constexpr size_t strlen_smart(char* baseChar) {
... constexpr function
}
inline size_t strlen_smart(char* baseChar) {
... runtime function
}
注意:这个问题一般适用于这个概念。有 2 个单独的函数用于运行时和 constexpr,而不是给出的示例函数。
免责声明:将编译器设置为 -O3(优化级别)足以修复 99.9% 的静态 char 优化,从而使上述所有示例“毫无意义”。但这与这个问题无关,因为它适用于其他“示例”,而不仅仅是strlen。
【问题讨论】:
-
请记住,即使一个函数是
constexpr和inline,传递的参数是常量,并且函数结果作为常量有效,该函数可能仍然 i> 如果在不需要常量表达式的上下文中使用,则在运行时执行。 (从技术上讲,它也可以在运行时在需要常量表达式的上下文中执行,但这不是有用的编译器所做的事情。)您不希望在运行时调用慢版本,即使参数是常量。 -
@hvd 我从示例中删除了“const”以避免混淆。同样是的,选择优化(如果可能)仍然取决于“编译器”。然而,关键是要确保最有效的变体在运行时运行。同时仍然有利于编译器优化。
-
我明白,但这不是我的意思。我的意思只是警告你,如果你尝试任何相当于
is_constant(expr) ? strlen_const(expr) : strlen_runtime(expr)的东西,这不会阻止strlen_const(expr)在运行时被调用。 -
baseChar+sizeof(char)-- 不,只是没有。 -
C++ 标准演进工作组的 Here's a document 讨论了类似问题并提出了几种解决方法(通过语言扩展或更改)。但是,据我了解,C++1y 中
constexpr函数的放宽应该已经大大减少了这个问题。
标签: c++ optimization c++11 compiler-optimization