Подтвердить что ты не робот

Почему использование возведения в степень (например, 10 ^ 6) занимает в 4 раза дольше, чем использование обозначения калькулятора (например, 1e6) в R?

Использование научной нотации 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

Почему это так, что R recomputes 10^6 примерно в то же время, что и он вычисляет exp{6*log(10)}? Я понимаю, что R выполняет функцию при вычислении 10^6, но почему она была закодирована таким образом?

4b9b3361

Ответ 1

Это потому, что 1e6 является constant и распознается как таковой парсером, тогда как 10^6 анализируется как вызов функции, который должен (путем вызова функции ^()). Поскольку первый избегает дорогостоящих издержек вызова функции, оценка его намного быстрее!

class(substitute(1e6))
# [1] "numeric"
class(substitute(10^6))
# [1] "call"

Чтобы лучше видеть, что это вызов, вы можете его рассеять так:

as.list(substitute(10^6))
# [[1]]
# `^`
# 
# [[2]]
# [1] 10
# 
# [[3]]
# [1] 6

Несколько других интересных случаев:

## 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"

Ответ 2

В случае 1e6 вы указываете буквальное числовое значение. Там никаких расчетов не происходит.

Когда вы запрашиваете 10^6, R выполняет работу по повышению 10 до 6-й мощности. ^ - числовой оператор. Он не делает ничего особенного для базы 10. Он не знает разницы между 10^6 и 12^14. Он должен выполнить расчет, чтобы найти ответ.