Schleifen in R sind aus demselben Grund langsam, aus dem jede interpretierte Sprache langsam ist: Jede Operation bringt viel zusätzliches Gepäck mit sich.
Schauen Sie R_execClosure
ineval.c
(dies ist die Funktion, die aufgerufen wird, um eine benutzerdefinierte Funktion aufzurufen). Es ist fast 100 Zeilen lang und führt alle Arten von Operationen aus - Erstellen einer Ausführungsumgebung, Zuweisen von Argumenten zur Umgebung usw.
Überlegen Sie, wie viel weniger passiert, wenn Sie eine Funktion in C aufrufen (Args auf Stack, Jump, Pop Args drücken).
Deshalb erhalten Sie Timings wie diese (wie Joran im Kommentar hervorhob, ist es nicht wirklich apply
schnell; es ist die interne C-Schleife mean
, die schnell ist. Es apply
ist nur normaler alter R-Code):
A = matrix(as.numeric(1:100000))
Verwenden einer Schleife: 0,342 Sekunden:
system.time({
Sum = 0
for (i in seq_along(A)) {
Sum = Sum + A[[i]]
}
Sum
})
Mit Summe: unermesslich klein:
sum(A)
Es ist ein wenig beunruhigend, weil die Schleife asymptotisch genauso gut ist wie sum
; Es gibt keinen praktischen Grund, warum es langsam sein sollte. Mit jeder Iteration wird nur mehr zusätzliche Arbeit geleistet.
Also bedenken Sie:
# 0.370 seconds
system.time({
I = 0
while (I < 100000) {
10
I = I + 1
}
})
# 0.743 seconds -- double the time just adding parentheses
system.time({
I = 0
while (I < 100000) {
((((((((((10))))))))))
I = I + 1
}
})
(Dieses Beispiel wurde von Radford Neal entdeckt )
Weil (
in R ein Operator ist und tatsächlich jedes Mal, wenn Sie ihn verwenden, eine Namenssuche erfordert:
> `(` = function(x) 2
> (3)
[1] 2
Oder im Allgemeinen haben interpretierte Operationen (in jeder Sprache) mehr Schritte. Natürlich bieten diese Schritte Vorteile auch: Sie konnte nicht tun , dass (
Trick in C.
system.time
Kriege in den Antworten beginnen ...