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

Why is assignment slower when there's an implicit conversion?

本文关键字:速度 分配 转换 为什么      更新时间:2023-10-16

如果有类似的问题,请直接告诉我,我安静地搜索了一段时间,但没有找到任何东西。

反向:

我只是在玩,发现了一些我无法完全解释的行为。。。对于基元类型,当存在隐式转换时,赋值运算符=与显式赋值相比需要更长的时间。

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平均执行相同的操作(每次都不同,但没有明显的差异)。它们都优于隐式赋值。

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。但任务中到底发生了什么?

谢谢!

如果你想知道为什么有什么事情在幕后发生,最好的地方是。。。等等隐藏:-)

这意味着要检查编译器生成的汇编语言。

C++环境最好被认为是运行C++代码的抽象机器。标准(主要)规定了行为,而不是实现细节。一旦你离开标准的界限,开始思考下面会发生什么,C++源代码就没有什么帮助了——你需要检查计算机运行的实际代码,编译器输出的东西(通常是机器代码)。

可能是编译器丢弃了循环,因为它每次都在计算相同的东西,所以只需要做一次。如果它可以确定您不使用结果,那么它可能会完全丢弃代码。

许多个月前,VAX Fortran编译器(我确实说过许多个月)在给定的基准测试中比竞争对手高出几个数量级。

这正是因为的原因。它已经确定没有使用循环的结果,因此优化了整个循环。


你可能需要注意的另一件事是测量工具本身。当你谈论1/10000持续时间时,你的结果可能会被最轻微的噪音淹没。

有一些方法可以减轻这些影响,比如确保你测量的东西是实质性的(例如超过10秒),或者使用统计方法来消除任何噪音。

但底线是,可能是测量方法导致了你所看到的结果。

#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

它们完全一样。

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