float和int比较需要额外的时间吗?

如果你有一个浮点数double num_float = 5.0; 和以下两个条件。

if(num_float > 3)
{
    //...
}

if(num_float > 3.0)
{
    //...
}

问:执行前面的比较是否会变慢,因为将3转换为浮点,还是根本没有差别?

很显然,我假设时间延迟最多可以忽略不计,但在一段时间(1)循环中复杂化,我认为从长远来看,相当一部分时间可能会丢失(如果真的慢)。


由于“as-if”规则,编译器允许在编译时将文字转换为浮点值。 一个好的编译器会这样做,如果这样会产生更好的代码。

为了确定地为您的编译器和目标平台回答您的问题,您需要检查编译器发出的内容以及它的执行方式。 但是,如果任何主流编译器都没有将两个if语句中的任何一个转换为最有效的代码,我会感到惊讶。


如果该值是一个常量,那么不应该有任何差异,因为编译器会将该常量转换为浮点数作为编译的一部分[除非编译器决定使用“compare float with integer”指令]。

如果该值是一个整数VARIABLE,那么将会有一条额外的指令将整数值转换为一个浮点数[再次,除非编译器可以使用“比较浮点数与整数”指令]。

如果有的话,增加整个过程的时间多少取决于处理器,浮点指令如何工作等等。

如同性能真正重要的任何事情一样,测量替代方案。 最好在不止一种类型的硬件上(例如AMD和英特尔处理器,如果它是PC的话),然后决定哪个更好。 否则,您可能会发现自己调整了代码,以便在您的硬件上正常工作,但在其他某些硬件上会更糟糕。 这不是一个好的优化 - 除非你运行的唯一的机器是你自己的。


注意:这将需要用目标硬件重复。 下面的代码很好地说明了所说的。


常量:

bool with_int(const double num_float) {
  return num_float > 3;
}

bool with_float(const double num_float) {
  return num_float > 3.0;
}

g ++ 4.7.2( -O3 -march=native ):

with_int(double):
  ucomisd       .LC0(%rip), %xmm0
  seta  %al
  ret
with_float(double):
  ucomisd       .LC0(%rip), %xmm0
  seta  %al
  ret
.LC0:
  .long 0
  .long 1074266112

铿锵3.0( -O3 -march=native ):

.LCPI0_0:
  .quad 4613937818241073152     # double 3.000000e+00
with_int(double):                           # @with_int(double)
  ucomisd       .LCPI0_0(%rip), %xmm0
  seta  %al
  ret

.LCPI1_0:
  .quad 4613937818241073152     # double 3.000000e+00
with_float(double):                        # @with_float(double)
  ucomisd       .LCPI1_0(%rip), %xmm0
  seta  %al
  ret

结论:如果与常量比较,没有区别。


与变量:

bool with_int(const double a, const int b) {
  return a > b;
}

bool with_float(const double a, const float b) {
  return a > b;
}

g ++ 4.7.2( -O3 -march=native ):

with_int(double, int):
  cvtsi2sd      %edi, %xmm1
  ucomisd       %xmm1, %xmm0
  seta  %al
  ret
with_float(double, float):
  unpcklps      %xmm1, %xmm1
  cvtps2pd      %xmm1, %xmm1
  ucomisd       %xmm1, %xmm0
  seta  %al
  ret

铿锵3.0( -O3 -march=native ):

with_int(double, int):                          # @with_int(double, int)
  cvtsi2sd      %edi, %xmm1
  ucomisd       %xmm1, %xmm0
  seta  %al
  ret

with_float(double, float):                       # @with_float(double, float)
  cvtss2sd      %xmm1, %xmm1
  ucomisd       %xmm1, %xmm0
  seta  %al
  ret

结论:Mats Peterson的回答已经解释过,所发布的指令在与变量进行比较时有所不同。

链接地址: http://www.djcxy.com/p/58533.html

上一篇: Is extra time required for float vs int comparisons?

下一篇: String comparison in Python: is vs. ==