为什么取幂(例如,10 ^ 6)比R中的计算器符号(例如,1e6)长4倍?

Xi'*_*'an 21 performance time r exponentiation coding-efficiency

10^6在R代码中使用科学记数法(正如我通常所做的那样)导致计算时间明显长于使用计算器表示1e6:

> system.time(for (t in 1:1e7) x=10^6) 
  utilisateur     système      écoulé 
        4.792       0.000       4.281 
> system.time(for (t in 1:1e7) x=1e6) 
 utilisateur     système      écoulé 
       0.804       0.000       1.051
> system.time(for (t in 1:1e7) x=exp(6*log(10)))
 utilisateur     système      écoulé 
       6.301       0.000       5.702
Run Code Online (Sandbox Code Playgroud)

为什么R会10^6在计算的大致相同的时间内重新计算exp{6*log(10)}?我理解R在计算时执行一个函数的事实10^6,但为什么它以这种方式编码?

Jos*_*ien 31

这是因为1e6是一个常量,并且被解析器识别,而10^6被解析为函数调用,必须进一步评估(通过调用函数^()).由于前者避免了函数调用的昂贵开销,因此评估它要快得多!

class(substitute(1e6))
# [1] "numeric"
class(substitute(10^6))
# [1] "call"
Run Code Online (Sandbox Code Playgroud)

为了更好地看到它是一个电话,您可以像这样剖析它:

as.list(substitute(10^6))
# [[1]]
# `^`
# 
# [[2]]
# [1] 10
# 
# [[3]]
# [1] 6
Run Code Online (Sandbox Code Playgroud)

其他一些有趣的案例:

## negative numbers are actually parsed as function calls
class(substitute(-1))
[1] "call"

## when you want an integer, 'L' notation lets you avoid a function call 
class(substitute(1000000L))
# [1] "integer"
class(substitute(as.integer(1000000)))
# [1] "call"
Run Code Online (Sandbox Code Playgroud)

  • @西安是的,R使用尾随的"L"来表示整数,它与`-`作为函数调用的处理方式不同.据我所知,没有执行函数调用就没有办法提供负常量---没有"1N"等. (2认同)

MrF*_*ick 6

1e6您指定文字数值的情况下.那里没有计算.

当你提出要求时10^6,R做了提高10到6次幂的工作.这^是一个数字运算符.它不会做什么特别的底座10.不知道之间的不同10^612^14.必须进行计算才能找到答案.

  • 赋予 10 个特殊状态会使解析器复杂化。我显然没有做过任何测试,但与偶尔的功率计算相比,这可能会减慢速度。 (3认同)