R'deki döngüler yavaştır, çünkü herhangi bir yorumlanan dil yavaştır: her işlem etrafında çok fazla ekstra bagaj taşır.
Bak R_execClosure
içindeeval.c
(bu kullanıcı tanımlı bir işlev çağrısı için denilen işlevdir). Yaklaşık 100 satır uzunluğundadır ve her türlü işlemi gerçekleştirir - yürütme için bir ortam oluşturmak, ortama argümanlar atamak, vb.
C'de bir işlevi çağırdığınızda ne kadar az olduğunu düşünün (yığın, atlama, args için değiştirgeleri itin).
İşte bu yüzden böyle zamanlamalar elde edersiniz (joran'ın yorumda belirttiği gibi, aslında apply
bu hızlı değildir; hızlı olan dahili C döngüsüdür mean
. apply
Sadece normal eski R kodudur):
A = matrix(as.numeric(1:100000))
Döngü kullanma: 0,342 saniye:
system.time({
Sum = 0
for (i in seq_along(A)) {
Sum = Sum + A[[i]]
}
Sum
})
Toplam kullanarak: ölçülemeyecek kadar küçük:
sum(A)
Bu biraz endişe verici çünkü asimptotik olarak döngü aynı derecede iyidir sum
; yavaş olması için pratik bir neden yok; sadece her yinelemede daha fazla ekstra çalışma yapıyor.
Öyleyse düşünün:
system.time({
I = 0
while (I < 100000) {
10
I = I + 1
}
})
system.time({
I = 0
while (I < 100000) {
((((((((((10))))))))))
I = I + 1
}
})
(Bu örnek Radford Neal tarafından keşfedildi )
Çünkü (
R bir operatördür ve aslında onu her kullandığınızda bir ad araması gerektirir:
> `(` = function(x) 2
> (3)
[1] 2
Veya genel olarak, yorumlanan işlemlerin (herhangi bir dilde) daha fazla adımı vardır. Tabii ki, bu adımlar aynı zamanda faydalar da sağlıyor: Bu numarayı C'de yapamazsınız(
.
system.time
cevapları savaşları ... başlayacak