2014-10-17 13 views
8

Tamam, cevabı biliyorum, ancak this question'dan esinlenerek, aşağıdakiler hakkında güzel fikirler almak istiyorum: Aşağıdaki Rcpp alıştırması ca. Dahili exp()'dan% 15 daha hızlı (uzun vektörler için)? Hepimiz Rcpp'nin R/C API'sine bir sarıcı olduğunu biliyoruz, bu yüzden biraz daha kötü bir performans beklemeliyiz.Kendiliğinden yazılan bir Rcpp vektörel matematiksel fonksiyonu, temel karşılıklarından daha hızlı mıdır?

Rcpp::cppFunction(" 
    NumericVector exp2(NumericVector x) { 
     NumericVector z = Rcpp::clone(x); 
     int n = z.size(); 
     for (int i=0; i<n; ++i) 
     z[i] = exp(z[i]); 
     return z; 
    } 
") 

library("microbenchmark") 
x <- rcauchy(1000000) 
microbenchmark(exp(x), exp2(x), unit="relative") 
## Unit: relative 
##  expr  min  lq median  uq  max neval 
## exp(x) 1.159893 1.154143 1.155856 1.154482 0.926272 100 
## exp2(x) 1.000000 1.000000 1.000000 1.000000 1.000000 100 
+0

iyi tahmin: lokal R arasındaki derleyici bayrakları/optimizasyon düzeylerindeki fark CRAN ve 'cppFunction' derlenen olarak derlenmiş? Rcpp kodunu derlerken optimizasyon için bu ve potansiyel olarak daha fazla fırsat (Rcpp'de kodlanmış tip bilgisinden yararlanarak) –

+0

@KevinUshey: Kendi başıma R'yi derledim. Rcpp için aynı derleyici bayraklarını kullanıyorum. – gagolews

+1

Sistemimde 'exp' daha hızlıdır. – Roland

cevap

8

Taban R daha çok biz bunu yapmadık tarafından biraz kazanabilirsiniz NA kontrol yapmak eğilimindedir. Ayrıca döngü açma gibi hileler yaparak (Rcpp Şekerinde olduğu gibi) hala daha iyi yapabileceğimizi unutmayın.

yüzden

Rcpp::cppFunction("NumericVector expSugar(NumericVector x) { return exp(x); }") 

eklendi ve bununla ben başka bir kazanç elde - kullanıcı tarafında daha az kod ile:

R> microbenchmark(exp(x), exp2(x), expSugar(x), unit="relative") 
Unit: relative 
     expr  min  lq mean median  uq  max neval 
     exp(x) 1.11190 1.11130 1.11718 1.10799 1.08938 1.02590 100 
    exp2(x) 1.08184 1.08937 1.07289 1.07621 1.06382 1.00462 100 
expSugar(x) 1.00000 1.00000 1.00000 1.00000 1.00000 1.00000 100 
R> 
+0

NA kontrolüne ilişkin noktanızı anladığımdan emin değilim. 'exp2'' NA', 'Inf',' NaN' girişlerini ele alır. – Roland

+0

@Roland Rcpp, R'ye göre (biraz) daha hızlı NA kontrolüne sahiptir. Aynı değerlendirme ölçütlerini kullanırsam, –

+0

'exp' hala daha hızlıdır. – Roland

5

gerçekten performans iyileştirmeleri elde etmek istiyorsanız, kod vardır temel donanımsal eşzamanlılıktan yararlanmak için yazılır. Bunu RcppParallel paketini kullanarak yapabilir ve bunun için parallelFor ideal bir gemi olacaktır.

R/C++'un daha modern bir uygulamasını da deneyebilirsiniz. Birkaç gün içinde piyasaya sürülen Rcpp11'un bir sonraki sürümü, otomatik olarak dişli şekere sahip olacak ve expSugar ile önceki cevabı daha iyi hale getirecek.

düşünün: Rcpp ile

#include <Rcpp.h> 
using namespace Rcpp ; 

// [[Rcpp::export]] 
NumericVector exp2(NumericVector x) { 
    NumericVector z = Rcpp::clone(x); 
    int n = z.size(); 
    for (int i=0; i<n; ++i) 
     z[i] = exp(z[i]); 
    return z; 
} 

// [[Rcpp::export]] 
NumericVector expSugar(NumericVector x) { 
    return exp(x) ; 
} 

/*** R 
    library(microbenchmark) 
    x <- rcauchy(1000000) 
    microbenchmark(exp(x), exp2(x), expSugar(x)) 
*/ 

alıyorum:

$ RcppScript /tmp/exp.cpp 

> library(microbenchmark) 

> x <- rcauchy(1e+06) 

> microbenchmark(exp(x), exp2(x), expSugar(x)) 
Unit: milliseconds 
     expr  min  lq median  uq  max neval 
     exp(x) 7.027006 7.222141 7.421041 8.631589 21.78305 100 
    exp2(x) 6.631870 6.790418 7.064199 8.145561 31.68552 100 
expSugar(x) 6.491868 6.761909 6.888111 8.154433 27.36302 100 

diğer yanıtlar açıklandığı gibi ... vb çeşitli inlining, açıklanabilir hangi Yani güzel, ama biraz anecdotic gelişme yorumlar. Rcpp11 ve otomatik dişli şekerli

, alıyorum:

$ Rcpp11Script /tmp/exp.cpp 

> library(microbenchmark) 

> x <- rcauchy(1e+06) 

> microbenchmark(exp(x), exp2(x), expSugar(x)) 
Unit: milliseconds 
     expr  min  lq median  uq  max neval 
     exp(x) 7.029882 7.077804 7.336214 7.656472 15.38953 100 
    exp2(x) 6.636234 6.748058 6.917803 7.017314 12.09187 100 
expSugar(x) 1.652322 1.780998 1.962946 2.261093 12.91682 100 
+0

Gerçekten Rcpp11 CRAN prömiyeri için sabırsızlanıyorum! İyi şanslar arkadaşlar! – gagolews

+1

Ya trick veya tweet;) –