una - ¿Por qué la exponenciación(por ejemplo, 10 ^ 6) toma 4 veces más que la notación de la calculadora(por ejemplo, 1e6) en R?
que significa fx en las calculadoras (2)
El uso de la notación científica 10^6
en un código R (como lo hago habitualmente) da como resultado un tiempo de computación significativamente más largo que el uso de la representación de calculadora 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
¿Por qué es el caso de que R vuelve a calcular 10^6
aproximadamente en el mismo tiempo que calcula exp{6*log(10)}
? Entiendo el hecho de que R ejecuta una función al calcular 10^6
, pero ¿por qué se codificó de esta manera?
En el caso de 1e6
está especificando un valor numérico literal. No hay ningún cálculo que suceda allí.
Cuando solicitas 10^6
, R hace el trabajo de aumentar 10 a la sexta potencia. El ^
es un operador numérico. No hace nada especial para la base 10. No conoce las diferencias entre 10^6
y 12^14
. Debe hacer el cálculo para encontrar la respuesta.
Esto se debe a que 1e6
es una constant , y el analizador lo reconoce como tal, mientras que 10^6
se analiza como una llamada de función que debe evaluarse (mediante una llamada a la función ^()
). Ya que el primero evita la costosa sobrecarga de una llamada de función, ¡evaluarla es mucho más rápido!
class(substitute(1e6))
# [1] "numeric"
class(substitute(10^6))
# [1] "call"
Para ver mejor que es una llamada, puede analizarla así:
as.list(substitute(10^6))
# [[1]]
# `^`
#
# [[2]]
# [1] 10
#
# [[3]]
# [1] 6
Algunos otros casos interesantes:
## 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"