Рассмотрят следующие функции foo
и bar
(отличаются только предупреждением печати) и их R эквиваленты fooR
и barR
:Почему Rcpp :: warning() работает медленнее, чем предупреждение R?
cppFunction('
void foo() {
int i = 0;
while (i < 1e3) {
i++;
}
return;
}')
cppFunction('
void bar() {
int i = 0;
while (i < 1e3) {
i++;
Rcpp::warning("hello world!");
}
return;
}')
fooR <- function() {
i = 0;
while (i < 1e3) {
i = i+1;
}
}
barR <- function() {
i = 0;
while (i < 1e3) {
i = i+1;
warning("hello world!")
}
}
Очевидно, что печать предупреждение делает функцию медленнее, но разница между R и Rcpp огромна (200 в несколько раз медленнее против 5000 раз медленнее!):
> benchmark(foo(), bar())
test replications elapsed relative user.self sys.self user.child sys.child
2 bar() 100 5.156 5156 5.156 0 0 0
1 foo() 100 0.001 1 0.000 0 0 0
There were 50 or more warnings (use warnings() to see the first 50)
> benchmark(fooR(), barR())
test replications elapsed relative user.self sys.self user.child sys.child
2 barR() 100 11.102 213.5 11.104 0 0 0
1 fooR() 100 0.052 1.0 0.052 0 0 0
There were 50 or more warnings (use warnings() to see the first 50)
Почему это так? Можно ли это предотвратить?
Очевидно, Rcpp должен сделать больше работы, чтобы отправить предупреждение в поток stderr R. Вы можете посмотреть исходный код, чтобы исследовать это. Однако почему вас это беспокоит? У вас есть прецедент, в котором так много предупреждений? – Roland
@Roland Мне нужно проверить входные значения для исключений и возвращать предупреждения в каждом случае - вот как я заметил, что, похоже, это замедление. – Tim
Сотни предупреждений не очень полезны. Я попытался бы избежать этого и использовать функцию для проверки ввода, которая объединяет эти многочисленные предупреждения в одно или несколько предупреждений или, возможно, даже возвращает ошибку. – Roland