Почему **0.5 кажется более эффективным, чем sqrt()

Я попытался измерить скорость этих двух способов извлечения квадратного корня:

> system.time(expr = replicate(10000, 1:10000 ** (1/2)))
##   user  system elapsed 
##  0.027   0.001   0.028 
> system.time(expr = replicate(10000, sqrt(1:10000)))
##   user  system elapsed 
##  3.722   0.665   4.494 

Если функция sqrt() не может конкурировать с ** 0.5, зачем нам такая функция?

(система — OS X Yusemite, версия R — 3.1.2)


person Lytze    schedule 17.03.2015    source источник
comment
См. ?Syntax для приоритета оператора. Возведение в степень ^ имеет более высокий приоритет, чем оператор последовательности :. Сравните 1:4 ^ (0.5); 1:(4 ^ (0.5)); (1:4) ^ (0.5)   -  person Henrik    schedule 17.03.2015
comment
Перед сравнением двух альтернатив вы всегда должны убедиться, что они дают идентичные результаты.   -  person Roland    schedule 17.03.2015


Ответы (2)


Вы забыли важные скобки. Вот тайминги после исправления этого:

system.time(expr = replicate(10000, (1:10000) ** (1/2)))
#user  system elapsed 
#4.76    0.32    5.12 
system.time(expr = replicate(10000, sqrt(1:10000)))
#user  system elapsed 
#2.67    0.57    3.31
person Roland    schedule 17.03.2015

Чтобы добавить к ответу @Roland, вы попали в Приоритет операторов "ловушка". ^ предшествует : ("** преобразуется в синтаксическом анализаторе в ^" в соответствии с документацией ?"**")

Что действительно произошло, так это

`:`(1, 10000 ** (1/2))

Это означает, что сначала вы запустили ** и только потом 1:..

Совет на будущее, старайтесь отлаживать свой код перед выполнением сложных операций, например, тестированием.

1:5 ** (1/2)
## [1] 1 2
sqrt(1:5)
## [1] 1.000000 1.414214 1.732051 2.000000 2.236068 

Раскрыл бы проблему.

person David Arenburg    schedule 17.03.2015
comment
** — довольно распространенный способ обозначения возведения в степень в других языках. Наверное, так они это придумали. - person Dason; 17.03.2015