C++ 这是微优化的一种形式吗?
C++ Is this a form of micro optimization
微优化,还是根本不是优化?
void Renderer::SetCamera(FLOAT x, FLOAT y, FLOAT z) {
// Checking for zero before doing addition?
if (x != 0) camX += x;
if (y != 0) camY += y;
if (z != 0) camZ += z;
// Checking if any of the three variables are not zero, and performing the code below.
if (x != 0 | y != 0 | z != 0) {
D3DXMatrixTranslation(&w, camX, camY, camZ);
}
}
运行具有 vector.size(( 条件的 for.. 循环会强制应用程序在每个循环上重新计算向量中的元素吗?
std::vector<UINT> vect;
INT vectorSize = vect.size();
for (INT Index = 0; Index < vectorSize; Index++) {
// Do vector processing
}
// versus:
std::vector<UINT> vect;
for (INT Index = 0; Index < vect.size(); Index++) {
// Do vector processing
}
我正在使用Visual Studio,至于第二个问题,它似乎是编译器可以优化的东西,但我只是不确定。
根据向量的实现,编译器可能会也可能不会理解大小不会更改。毕竟,您在循环中调用不同的向量函数,其中任何一个都可能改变大小。
由于 vector 是一个模板,那么编译器知道它的一切,所以如果它真的很努力,它可以理解大小不会改变,但这可能工作量太大了。
通常,你会想这样写:
for (size_t i = 0, size = vect.size(); i < size; ++i)
...
当我们这样做时,迭代器也使用了类似的方法:
for (list<int>::iterator i = lst.begin(), end = lst.end(); i != end; ++i)
...
编辑:我错过了第一部分:
这是优化吗?
if (x != 0) camX += x;
if (y != 0) camY += y;
if (z != 0) camZ += z;
不。首先,即使它们是 int,也不会是优化,因为在值可能大多数时候不为零时进行检查和分支是更多的工作。
其次,更重要的是,它们是浮动的。这意味着除了你不应该直接将它们与 0 进行比较这一事实之外,它们基本上几乎永远不会完全等于 0。因此,if
是99.9999%正确的。
同样的事情也适用于此:
if (x != 0 | y != 0 | z != 0)
但是,在这种情况下,由于矩阵转换可能很昂贵,因此您可以执行以下操作:
#define EPS 1e-6 /* epsilon */
if (x > EPS || x < -EPS || y > EPS || y < -EPS || z > EPS || z < -EPS)
现在是的,与矩阵乘法相比,这可能是一种优化。
另请注意,我使用了||
,例如,如果从一开始就x > EPS
为真(它不会计算其余部分(,那么它会短路,但|
这种情况不会发生。
我怀疑在许多架构上,前三行是反优化的,因为它们可能会引入浮点比较,然后分支,这可能比总是做加法慢(即使它是浮点(。
另一方面,在进行转换之前,确保至少有一个组件不为零似乎是合理的。
对于第二种情况,size
必须是恒定的时间,并且几乎肯定会内联到直接访问vector
的大小。它很可能是完全可优化的。也就是说,有时它可以通过保存大小来使代码/循环更易于阅读,因为这清楚地表明您断言大小在循环期间不会改变。
首先,关于vector.size()
,请参阅这个问题。附带说明一下,我还没有看到std::vector::size()
不是 O(1( 的实现。
if (x != 0) camX += x;
这种cmp
和随之而来的jne
无论如何都会比简单地添加变量x
慢。编辑:除非您预计camX
缓存未命中率超过 50
第一个可能是悲观的,对 0 的检查可能比加法慢。最重要的是,在调用D3DXMatrixTranslation
之前的检查中,您使用|
而不是短路逻辑或||
。由于函数调用之前的检查可能节省时间(甚至在语义上是必要的(,因此将整个代码包装在该检查中,
void Renderer::SetCamera(FLOAT x, FLOAT y, FLOAT z) {
if (x != 0 || y != 0 || z != 0) {
camX += x;
camY += y;
camZ += z;
D3DXMatrixTranslation(&w, camX, camY, camZ);
}
}
如果所有x
、y
和z
都为零,则无需执行任何操作,否则,请执行所有操作。
对于第二种,如果编译器可以确定循环运行时大小不会更改,则可以将vector.size()
提升到循环外部。如果编译器无法确定这一点,则不得将size()
计算提升到循环之外。
当您知道大小不变时,自己这样做是一种很好的做法。
- 有符号的int和int-有没有一种方法可以在C++中区分它们
- 有一个打印语句的函数是一种糟糕的编程实践吗
- 有没有一种方法可以创建一个带有哈希表的数据库,该哈希表具有恒定时间查找功能
- 有没有一种方法可以在编译时获得作用域类名
- 对于C++中使用智能指针的指针算术限制,有没有一种变通方法
- 一种在C++中读取TXT配置文件的简单方法
- 有没有一种方法可以测量c++程序的运行时内存使用情况
- 有没有一种方法可以使用placement new将堆叠对象分配给分配的内存
- 在调用接收数组的方法时,模板化数组大小是不是一种糟糕的做法
- 将空基类优化对象强制转换为另一种类型是否会破坏严格的别名?
- 有没有一种方法可以关闭C++和Rust编译中的循环优化
- 有没有一种方法可以优化这个DP程序中的空间
- 元组作为一种返回类型,是经过优化的未处理值
- 是否引入了一种新的可变失败回报值优化
- 有没有一种更快的方法或优化我可以应用到我的即兴内存池
- LLVM clang编译器优化器以一种非常奇怪的方式重新排列代码,该怎么做
- 我怎样才能优化它以一种有效的方式运行
- C++ 这是微优化的一种形式吗?
- 我如何禁用c++返回值优化的一种类型
- 是否有一种方法来优化这个代码