2013-04-10 5 views
5

Warum ist der R-Code mit {} im Allgemeinen schneller als der mit (), Beispiel unten?Warum ist R-Code mit `{}` schneller als mit `()`?

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

Es ist nicht für mich, mit R-2.15.2 auf 64-Bit-Linux. Bitte geben Sie die Ausgabe von 'sessionInfo()' an. –

+5

Überprüfen Sie die [Blog von Radford Neal] (http://radfordneal.wordpress.com/2010/08/15/two-surpising-things-about-r/) – baptiste

+1

Ich würde auch ein reales Beispiel der Welt schätzen, wo Die oben genannten Unterschiede (die ich nicht reproduzieren kann) würden einen spürbaren Unterschied machen, wie Sie sich einer Aufgabe annähern würden. – Chase

Antwort

9

baptiste bereits Radford Neal ‚s Blog in den Kommentaren verlinkt sind.
Aber da die SE Menschen auf externe Seiten keine Links mögen, lassen Sie mich eine interessante Bemerkung des Autors zitieren selbst (33) Kommentar:

Ja, Klammern sind 2,13 immer noch langsamer als geschweiften Klammern in R. 1, und in der letzten R 2.14.1, wenn auch nicht so viel wie zuvor (ein Patch, den ich vorgeschlagen habe, um den allgemeinen Overhead in eingebauten Funktionen zu reduzieren, wurde in späteren Releases eingebaut, was diesen Unterschied reduzierte).

Es gibt keinen guten Grund dafür, dass Klammern langsamer sind. Ich schlug eine weitere Änderung (auf ein paar Zeilen Code) vor, die Klammern beschleunigen würde. Luke Tierney antwortete, dass dieser Patch auf keinen Fall in R integriert werden sollte, auf der Grundlage, dass Klammern wie sqrt ein Operator sind, und dass daher im Code keine Klammern gesetzt werden sollten, die von der Implementierung von Operatoren wie sqrt abweichen .

, dass Wissen, () erscheint ein Bediener zu sein - ähnlich wie eine Funktion im Grunde nichts zu tun -
während { } ist ein Sprachkonstrukt.
Die Klammern () enthalten einen Overhead-Code, der allen Operatoren gemeinsam ist, was sie eigentlich nicht benötigt.

+0

Diese Antwort ist falsch: '{' sind * auch * heutzutage ein Operator in R, kein Sprachkonstrukt! Und wie '(', it Es kann sein, dass sich dies geändert hat, seit der Kommentar (und diese Antwort) geschrieben wurde. –

5

Lukas beantwortete die Frage gut, aber hier sind einige Zeitpläne für die Interessenten (die effektiv durch Vektorisierung Ihres Codes entfernt werden können).

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 

Ungefähr 5 Millisekunden Unterschied bei 1e5 Schleifenlängen. Also lassen Sie uns die Schleifen entfernen:

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 

Der Unterschied ist jetzt ~ 0,5 Millisekunden.

Verwandte Themen