Встроенные функции в R обычно оптимизированы? - PullRequest
5 голосов
/ 12 июля 2011

У меня есть некоторый письменный код для вычисления коэффициента корреляции в R. Однако я только что узнал, что пакет 'boot' предлагает corr () функции, которые делают ту же работу. Есть встроенные функции в R обычно более эффективный и быстрый, чем аналогичные написать с нуля?

Спасибо.

Ответы [ 4 ]

5 голосов
/ 12 июля 2011

Я не думаю, что есть один конкретный ответ на этот вопрос, так как он будет сильно отличаться в зависимости от конкретной функции, о которой вы спрашиваете. Некоторые функции в добавленных пакетах добавлены для удобства и являются просто оболочками вокруг базовых функций. Другие добавляются для расширения базовой функциональности или для решения некоторых других проблем с базовыми функциями. Некоторые из них, как вы предлагаете, добавлены, чтобы сократить время вычислений или стать более эффективными. И другие добавляются, потому что авторы пакетов поддержки считают, что решения в базе R в некотором смысле просто неверны.

В случае stats:::cor и boot:::corr похоже, что последний добавляет возможность взвешивания. Это не обязательно будет быстрее:

> dat <- matrix(rnorm(1e6), ncol = 2)
> system.time(
+ cor(dat[, 1],dat[, 2])
+ )
   user  system elapsed 
   0.01    0.00    0.02 
> system.time(
+ corr(dat)
+ )
   user  system elapsed 
   0.11    0.00    0.11 
3 голосов
/ 12 июля 2011

Это более-менее (т.е. не считая дрянного кода) сводится к вопросу, реализована ли определенная процедура в R или в виде кода C (++) или Fortran - если функция содержит вызов .Internal,.External, .C, .Fortran или .Call это означает, что это второй случай и, вероятно, он будет работать быстрее.Обратите внимание, что это ортогонально вопросу о том, является ли функция базой R или пакетом.

Тем не менее, вы всегда должны помнить, что эффективность является относительной вещью и всегда должна восприниматься в контексте всей задачи и взвешиватьсяс усилиями программиста, необходимыми для ускорения чего-либо.Это равносильно уменьшению времени выполнения с 1 с до 10 мс, переписать все для использования базы только потому, что пакеты являются злыми или потратить несколько часов на оптимизацию функции A, в то время как 90% фактического времени выполнения скрывается в функции B.

2 голосов
/ 13 июля 2011

Еще один момент заключается в том, что во встроенных R-функциях часто содержится много «упаковочного» материала, который выполняет проверку ошибок, переупорядочивает данные и т.д.передача на lm.fit и glm.fit соответственно для фактического сокращения числа.В вашем конкретном случае cor вызывает .Internal(cor(x, y, na.method, FALSE)) для корреляции Пирсона.Если (1) вам действительно нужна скорость и (2) вы хотите самостоятельно упорядочить данные и отказаться от проверки ошибок, иногда вы можете сэкономить время, вызвав внутреннюю функцию самостоятельно:

library(rbenchmark)
x <- y <- runif(1000)
benchmark(cor(x,y),.Internal(cor(x,y,4,FALSE)),replications=10000)
                            test replications elapsed relative user.self
1                      cor(x, y)        10000   1.131 5.004425     1.136
2 .Internal(cor(x, y, 4, FALSE))        10000   0.226 1.000000     0.224

Но, опять же, это зависит: мы не выигрываем много, когда матрицы большие, как в примере выше (так что время, потраченное на проверку ошибок относительно выполнения вычислений, намного больше) ...

x <- y <- rnorm(5e5)
benchmark(cor(x,y),.Internal(cor(x,y,4,FALSE)),replications=500)
                            test replications elapsed relative user.self
1                      cor(x, y)          500   5.402 1.013889     5.384
2 .Internal(cor(x, y, 4, FALSE))          500   5.328 1.000000     5.316
2 голосов
/ 12 июля 2011

Расширяя ответ Чейза, я не только думаю, что нет единого ответа на этот вопрос, но что этот вопрос не так хорош. Это очень неопределенно. Пожалуйста, посмотрите здесь , какие вопросы задать.
Кроме того, у меня такое ощущение, что ОП не знает о функции cor базы R, см. ?cor.

Мой ответ: Существуют специальные функции, которые чрезвычайно быстры, например, rowSums по сравнению с apply с sum. С другой стороны, существуют медлительности, которых можно избежать (если вы готовы потратить некоторое время на то, чтобы приступить к основам), но которые необходимо встроить из-за проектных решений. Рэдфорд Нил спорит об этом углу, см. Например одно из его последних сообщений на тему .

В целом, я думаю, что ответ на этот вопрос заключается в том, что я думаю, что философия R: R не самая быстрая лошадь в гонке, но определенно та, которая достигает наибольшего результата с наименьшим количеством кода, если это так. о данных.

В общем, я думаю, что не так уж и неправильно утверждать: чем более специализирована функция, тем выше вероятность того, что она будет очень быстрой (и написана на C или Fortran). Чем более общая и абстрактная функция, тем она медленнее (сравните скорости plyr Хэдли Уикхема с базовым семейством apply).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...