为什么在进行隐式转换时分配较慢?

时间:2015-03-26 08:42:06

标签: c++ casting static-cast

如果有类似的问题,请指导我,我搜索安静一段时间,但没有找到任何东西。

底色:

我只是在玩耍,发现了一些我无法完全解释的行为...... 对于原始类型,看起来就像隐式转换一样,赋值运算符=与显式赋值相比需要更长的时间。

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。但是这项工作到底发生了什么?

谢谢!

2 个答案:

答案 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

它们都完全一样。

由于您没有提供完整的示例,我只能猜测差异是由于您没有向我们展示的。