如果有类似的问题,请指导我,我搜索安静一段时间,但没有找到任何东西。
底色:
我只是在玩耍,发现了一些我无法完全解释的行为...... 对于原始类型,看起来就像隐式转换一样,赋值运算符=与显式赋值相比需要更长的时间。
int iTest = 0;
long lMax = std::numeric_limits<long>::max();
for (int i=0; i< 100000; ++i)
{
// I had 3 such loops, each running 1 of the below lines.
iTest = lMax;
iTest = (int)lMax;
iTest = static_cast<int>(lMax);
}
结果是c样式转换和c ++样式static_cast平均执行相同(每次都不同,但没有明显的差异)。 AND它们都优于隐式赋值。
Result:
iTest=-1, lMax=9223372036854775807
(iTest = lMax) used 276 microseconds
iTest=-1, lMax=9223372036854775807
(iTest = (int)lMax) used 191 microseconds
iTest=-1, lMax=9223372036854775807
(iTest = static_cast<int>(lMax)) used 187 microseconds
问题:
为什么隐式转换会导致更大的延迟?我猜可以在int溢出的赋值中检测到它,因此调整为-1。但是这项工作到底发生了什么?
谢谢!
答案 0 :(得分:3)
如果你想知道为什么会发生什么事情,最好看的地方是......等待它...... 在幕后。
这意味着检查编译器生成的汇编语言。
C ++环境最好被认为是运行C ++代码的抽象机器。标准(主要)指示行为而不是实现细节。一旦离开标准的界限并开始考虑下面发生的事情,C ++源代码就不再有用了 - 你需要检查计算机的实际代码正在运行,由编译器输出的东西(通常是机器代码)。
可能是编译器丢弃循环,因为它每次都计算相同的东西所以只需要执行一次。如果它可以确定你不使用结果,它可能会完全抛弃代码。
很多时候,VAX Fortran编译器(我确实说很多卫星)在给定的基准测试中表现优于其竞争对手几个数量级。
那是因为完全的原因。它确定了循环的结果没有被使用,因此优化了整个循环的存在。
您可能需要注意的另一件事是测量工具本身。当您谈论 1 / 10,000 th 的持续时间时,您的结果可能会淹没一点点的噪音。
有一些方法可以减轻这些影响,例如确保你测量的东西是实质性的(例如超过十秒),或使用统计方法消除任何噪音。
但最重要的是,它可能是导致您所看到的结果的衡量方法。
答案 1 :(得分:2)
#include <limits>
int iTest = 0;
long lMax = std::numeric_limits<long>::max();
void foo1()
{
iTest = lMax;
}
void foo2()
{
iTest = (int)lMax;
}
void foo3()
{
iTest = static_cast<int>(lMax);
}
使用-O3
产生的GCC 5编译:
__Z4foo1v:
movq _lMax(%rip), %rax
movl %eax, _iTest(%rip)
ret
__Z4foo2v:
movq _lMax(%rip), %rax
movl %eax, _iTest(%rip)
ret
__Z4foo3v:
movq _lMax(%rip), %rax
movl %eax, _iTest(%rip)
ret
它们都完全一样。
由于您没有提供完整的示例,我只能猜测差异是由于您没有向我们展示的。