2013-04-10 10 views
5

Perché il codice R con {} in generale è più veloce di quello con (), esempio di seguito?Perché il codice R con `{}` è più veloce di quello con `()`?

n=10000000 
w1=numeric(n) 
w2=numeric(n) 
r=rnorm(n) 


t1=Sys.time() 
for(i in 1:n) 
w1[i]=((r[i]^2))*(1*1) 
t1-Sys.time() 


t1=Sys.time() 
for(i in 1:n) 
w2[i]={{r[i]^2}}*{1*1} 
t1-Sys.time() 
+0

Non fa per me, utilizzando R-2.15.2 su Linux a 64 bit. Si prega di fornire output da 'sessionInfo()'. –

+5

controlla il [blog di Radford Neal] (http://radfordneal.wordpress.com/2010/08/15/two-surpising-things-about-r/) – baptiste

+1

Vorrei anche apprezzare un esempio reale di dove il le differenze identificate sopra (che non posso riprodurre BTW) farebbero una differenza tangibile nel modo in cui ti avvicineresti a un compito. – Chase

risposta

9

Baptiste già collegato Radford blog Neal s' nei commenti.
Ma dal momento che la gente SE non piace link a siti esterni, vorrei citare un interessante commento dello stesso autore (commento 33):

Sì, parentesi sono ancora più lento di parentesi graffe in R 2.13. 1 e nell'ultima R 2.14.1, anche se non di molto come prima (una patch che ho suggerito di ridurre l'overhead generale nelle funzioni built-in è stata incorporata nelle versioni successive, cosa che ha ridotto questa differenza).

Non c'è un buon motivo per le parentesi per essere più lento. Ho suggerito un altro cambiamento (a un paio di linee di codice) che velocizzasse le parentesi. Luke Tierney ha risposto che questa patch non dovrebbe mai essere incorporata in R, sulla base del fatto che le parentesi sono un operatore come sqrt e che quindi non dovrebbe esserci nulla nel codice che implementa le parentesi che parte dal modo in cui gli operatori come sqrt sono implementati .

Sapendo che, () sembra essere un operatore - molto simile a una funzione di fare praticamente nulla -
mentre { } è un costrutto del linguaggio.
Le parentesi () incorporano un codice di overhead comune a tutti gli operatori che in realtà non ne ha bisogno.

+0

Questa risposta è errata: '{' sono * anche * un operatore in R al giorno d'oggi, non un costrutto linguistico! E come '(', it può essere sovraccaricato. È possibile che questo sia cambiato poiché il commento (e questa risposta) è stato scritto, comunque. –

5

Lukas ha risposto gentilmente alla domanda, ma qui ci sono alcuni tempi sul sovraccarico per chi è interessato (che può essere efficacemente rimosso mediante il vettorizzazione del codice).

brace <- function(n){ 
w1=numeric(n) 
w2=numeric(n) 
r=rnorm(n) 
for(i in 1:n) 
w1[i]=((r[i]^2))*(1*1) 
} 


curly <- function(n){ 
w1=numeric(n) 
w2=numeric(n) 
r=rnorm(n) 
for(i in 1:n) 
w2[i]={{r[i]^2}}*{1*1} 
} 



microbenchmark(curly(1e5) , brace(1e5) , times = 50) 
Unit: milliseconds 
     expr  min  lq median  uq  max neval 
curly(1e+05) 311.4245 318.8916 324.1990 335.0928 400.8555 50 
brace(1e+05) 315.5428 323.8860 328.7982 350.7268 406.5785 50 

Circa una differenza di 5 millisecondi alle lunghezze di loop 1e5. Quindi rimuoviamo i loop:

braceV <- function(n){ 
w1=numeric(n) 
w2=numeric(n) 
r=rnorm(n) 
w1=((r^2))*(1*1) 
} 


curlyV <- function(n){ 
w1=numeric(n) 
w2=numeric(n) 
r=rnorm(n) 
w2={{r^2}}*{1*1} 
} 

microbenchmark(curlyV(1e5) , braceV(1e5) , times = 50) 
Unit: milliseconds 
      expr  min  lq median  uq  max neval 
curlyV(1e+05) 9.014361 9.284532 9.666867 10.81317 37.82510 50 
braceV(1e+05) 9.029408 9.373773 10.293302 10.83487 37.76596 50 

La differenza è ora intorno a ~ 0,5 millisecondi.

Problemi correlati