在C++中,将变量的限制存储在变量中比评估值更快吗?
例如:
这是一种较慢的使用方法
for(int i=0; i<n*n+2*n; ++i)
{ .... }
Run Code Online (Sandbox Code Playgroud)
而不是做以下?
for(int i=0, limit=n*n+2*n; i<limit; ++i)
{ .... }
Run Code Online (Sandbox Code Playgroud)
为清楚起见,假设n某个给定变量在循环过程中保持不变.
Bat*_*eba 21
如果n是全局声明的非volatile变量,那么行为
for (int i = 0; i < n * n + 2 * n; ++i)
是不确定.n * n + 2 * n即使另一个线程修改,也允许编译器进行优化以进行一次评估n.此外,如果另一个线程能够修改n,那么您应该采取措施避免同时读取和写入的可能性n(其行为未定义).考虑使用std::atomic<int>作为类型n.
limit无论如何,如果您希望在n程序控制到达for循环时停止条件依赖于observable 的值,那么无论出于何种性能考虑,都应该引入.因此,请考虑
for (int i = 0, limit = n * n + 2 * n; i < limit; ++i)
其优点是limit不会泄漏到周围的陈述范围内.
但是如果你能够,你总是可以向后运行循环:
for (int i = n * n + 2 * n - 1; i >= 0; --i)
要非常小心,虽然与unsigned类型,如果你采用这种想法.
在热点之外没关系.我的意思是 - 是的,在没有编译器优化的情况下,在调试中只计算一次值会更快,并且至少在发布时速度快.但它通常无关紧要.这样做更容易编写,阅读和维护.让我引用唐纳德克努特的名言:
真正的问题是程序员花费了太多时间来担心在错误的地方和错误的时间提高效率; 过早优化是编程中所有邪恶(或至少大部分)的根源.
话虽如此,我最近喜欢这种方式:
for (int i = 0, upperBound = n*n + 2*n /*or n*(n + 2)*/; i < upperBound; ++i)
{
}
Run Code Online (Sandbox Code Playgroud)
这样,范围upperBound仅限于for语句本身,并且不会渗透到不需要它的外部范围.