2013-02-14 13 views
9

Ho confrontato le prestazioni delle funzioni R integrate rnorm, qnorm e pnorm alle funzioni equivalenti di Matlab.R vs. Matlab: spiegazione della differenza di velocità per le funzioni rnorm, qnorm e pnorm

Sembra che le rnorm e pnorm funzioni sono 3-6 volte più lento in R rispetto al Matlab, mentre la funzione qnorm è ca. 40% più veloce in R. Ho provato il pacchetto Rcpp per accelerare le funzioni R utilizzando le librerie C corrispondenti che hanno comportato una diminuzione del tempo di esecuzione del ~ 30%, che è ancora significativamente più lento rispetto a Matlab per rnorm e pnorm.

Esiste un pacchetto disponibile che fornisce un modo più veloce di simulare le variabili casuali normalmente distribuite in R (oltre all'uso della funzione standard rnorm)?

+2

probabilmente avete capito questo già, ma l'altra cosa da notare è che la raccolta grosso blocco di numeri casuali è * molto * più veloce nella R di loro sceglierne uno per uno .. . ie 'rnorm (1e6)' è molto più veloce di 'vapply (seq (1e6), function (i) rnorm (1), numeric (1))' –

risposta

9

Per promuovere il mio commento a una risposta: sì, c'è.

library("sos"); findFn("Ziggurat") trova la funzione rziggurat nel pacchetto SuppDists; esso è implementato in C (o C++?), e la sua documentazione dice

Questa implementazione in esecuzione in R è pari a circa tre volte più veloce RNorm().

L'altro punto da notare, che può rendere tanto o più differenza nella pratica, è che raccogliendo grosso blocco di numeri casuali è molto più veloce in R di raccoglierli uno ad uno ... cioè rnorm(1e6) viene molto più veloce di vapply(seq(1e6),function(i) rnorm(1),numeric(1))

library("SuppDists") 
library("rbenchmark") 
n <- 1e5 
benchmark(rziggurat(n), 
      rnorm(n), 
      vapply(seq(n),function(x) rnorm(1),numeric(1))) 

##   test elapsed relative user.self 
## 2  rnorm(n)  1.138  13.233  1.140 
## 1 rziggurat(n)  0.086  1.000  0.088 
## 3 vapply(...) 29.043 337.709 29.046 
+0

Grazie Ben per questo suggerimento! In realtà migliora il tempo di esecuzione di un fattore 6 sulla mia macchina. Forse c'è un altro pacchetto che migliora anche il runtime per la funzione pnorm? – user1372987

+0

Si noti che l'implementazione di Ziggurat funziona solo su sistemi operativi a 32 bit. Ho messo qualcosa di meglio su CRAN all'inizio di quest'anno in [RcppZiggurat] (http://dirk.eddelbuettel.com/code/rcpp.ziggurat.html). –

10

vedo due questioni distinte qui, uno in ogni paragrafo:

  • Sì, ci sono differenze tra lingue/sistemi come R e Matlab. Parte di esso ha a che fare con l'interprete, la velocità dei loop, la velocità delle chiamate alle funzioni ecc. Pp. Rcpp può esserci d'aiuto rispetto a Matlab che ha un vero compilatore JIT. Abbiamo un confronto tra Matlab, R e R + Rcpp per un filtro Kalman nel recente articolo su RcppArmadillo.

  • Ci sono anche delle differenze nel codice compilato sottostante, e sì, R non ha sempre un'implementazione più veloce come R Core (correttamente a ragione IMHO) per precisione. (E Rcpp non aiuta di per sé: chiamiamo solo ciò che R ha internamente.) Questo era emerso ad es. Con l'esempio di Gibbs Sampler per MCMC che Darren Wilkinson aveva iniziato. Ho notato che l'R rgamma() è molto più lento di altri sistemi. Quindi, per arrivare alla tua domanda riguardo a N (0,1) si disegna in un modo più veloce: penso che abbiamo bisogno di un'implementazione Ziggurat contribuita. Quello è uno dei più veloci N (0,1) generatori là fuori, e pochi altri sistemi lo usano.

+0

Infatti: 'library (" sos "); findFn ("Ziggurat") 'trova http://finzi.psych.upenn.edu/R/library/SuppDists/html/ziggurat.html, che dice" Questa implementazione in esecuzione in R è approssimativamente tre volte più veloce di rnorm() . " –

+0

Grazie, Ben. Penso di averlo saputo una volta, ma l'ho archiviato come "buono, e ora ne ho bisogno dal C++ ..." e ho dimenticato. –

+0

probabilmente potresti semplicemente rubare il codice - è GPL ... –