2015-05-02 7 views
21

die wissenschaftliche Notation Mit 10^6 in einem R-Code Rechenzeit (wie ich üblicherweise tun) führt zu einer deutlich länger als den Rechner Darstellung mit 1e6:Warum die Verwendung der Potenzierung (z. B. 10^6) 4-mal länger dauert als die Verwendung der Kalkulatornotation (z. B. 1e6) in R?

> system.time(for (t in 1:1e7) x=10^6) 
    utilisateur  système  écoulé 
     4.792  0.000  4.281 
> system.time(for (t in 1:1e7) x=1e6) 
utilisateur  système  écoulé 
     0.804  0.000  1.051 
> system.time(for (t in 1:1e7) x=exp(6*log(10))) 
utilisateur  système  écoulé 
     6.301  0.000  5.702 

Warum ist es der Fall, dass R 10^6 in etwa die neu berechnet Wie oft berechnet es exp{6*log(10)}? Ich verstehe die Tatsache, dass R eine Funktion ausführt, wenn 10^6 berechnet wird, aber warum wurde es auf diese Weise codiert?

+2

Ich würde vermuten, dass man ein numerisches Literal, das nur übersetzt werden muss, während das andere ein Ausdruck ist, der zuerst bewertet werden muss. –

+1

Warum denken Sie, dass R '10^6' über 'exp (6 * log (10))' 'berechnet? – cryo111

+0

@ cryo111: Ich weiß nicht, wie R '10^6' berechnet, aber es dauert so lange wie' exp (6 * log (10)) '. Ich werde diesen Satz umformulieren, danke. –

Antwort

29

Es ist, weil 1e6 ein constant ist, und ist als solche durch den Parser erfasst, während 10^6 als Funktionsaufruf analysiert wird, die weiter ausgewertet werden muss (durch einen Aufruf der Funktion ^()). Da ersteres den teuren Overhead eines Funktionsaufrufs vermeidet, ist die Auswertung viel schneller!

class(substitute(1e6)) 
# [1] "numeric" 
class(substitute(10^6)) 
# [1] "call" 

besser zu sehen, dass es ein Anruf ist, können Sie es so sezieren kann:

as.list(substitute(10^6)) 
# [[1]] 
# `^` 
# 
# [[2]] 
# [1] 10 
# 
# [[3]] 
# [1] 6 

ein paar andere interessante Fälle:

## negative numbers are actually parsed as function calls 
class(substitute(-1)) 
[1] "call" 

## when you want an integer, 'L' notation lets you avoid a function call 
class(substitute(1000000L)) 
# [1] "integer" 
class(substitute(as.integer(1000000))) 
# [1] "call" 
+0

Sehr interessante Zusatzfälle! Aber rätselhaft. Ich hatte noch nie von der Verwendung des L gehört (aber es scheint keine Zeit zu sparen, wenn eine negative Zahl zugewiesen wird) –

+2

@ Xi'an Ja, Rs Verwendung eines nachgestellten "L" zur Angabe von ganzen Zahlen unterscheidet sich von seiner Behandlung von '- 'als Funktionsaufruf. Soweit ich weiß, gibt es einfach keine Möglichkeit, eine negative Konstante zu liefern, ohne einen Funktionsaufruf auszuführen - nein "1N" oder dergleichen. –

5

Bei 1e6 geben Sie einen literalen numerischen Wert an. Dort findet keine Berechnung statt.

Wenn Sie 10^6 anfordern, macht R die Arbeit, 10 bis zur 6. Potenz zu erhöhen. Der ^ ist ein numerischer Operator. Es tut nichts besonderes für Base 10. Es kennt nicht den Unterschied zwischen 10^6 und 12^14. Es muss die Berechnung durchführen, um die Antwort zu finden.

+0

Danke. Es ist traurig, dass 10 keinen Sonderstatus bekommt! –

+1

Wenn 10 spezielle Status vergeben würden, würde dies den Parser erschweren. Ich habe offensichtlich keine Tests gemacht, aber die Chancen werden die Dinge langsamer machen als die gelegentliche Berechnung der Energie. – kasterma