Các vòng lặp trong R chậm vì cùng một lý do khiến bất kỳ ngôn ngữ thông dịch nào cũng chậm: mọi hoạt động đều mang thêm rất nhiều hành lý.
Nhìn vào R_execClosure
trongeval.c
(đây là chức năng gọi để gọi một chức năng người dùng định nghĩa). Nó dài gần 100 dòng và thực hiện tất cả các loại hoạt động - tạo môi trường để thực thi, gán các đối số vào môi trường, v.v.
Hãy nghĩ xem sẽ ít hơn bao nhiêu khi bạn gọi một hàm trong C (đẩy args lên để xếp, nhảy, bật args).
Vì vậy, đó là lý do tại sao bạn nhận được thời gian như thế này (như joran đã chỉ ra trong nhận xét, nó không thực sự apply
nhanh; đó là vòng lặp C nội bộ trong mean
đó đang nhanh. apply
Chỉ là mã R cũ thông thường):
A = matrix(as.numeric(1:100000))
Sử dụng một vòng lặp: 0,342 giây:
system.time({
Sum = 0
for (i in seq_along(A)) {
Sum = Sum + A[[i]]
}
Sum
})
Sử dụng sum: nhỏ vô ưu:
sum(A)
Nó có một chút bối rối bởi vì, về mặt tiệm cận, vòng lặp cũng tốt như sum
; không có lý do thực tế nào mà nó phải chậm; nó chỉ làm thêm công việc mỗi lần lặp lại.
Vì vậy, hãy xem xét:
system.time({
I = 0
while (I < 100000) {
10
I = I + 1
}
})
system.time({
I = 0
while (I < 100000) {
((((((((((10))))))))))
I = I + 1
}
})
(Ví dụ đó được phát hiện bởi Radford Neal )
Bởi vì (
trong R là một toán tử và thực sự yêu cầu tra cứu tên mỗi khi bạn sử dụng nó:
> `(` = function(x) 2
> (3)
[1] 2
Hoặc, nói chung, các hoạt động được thông dịch (bằng bất kỳ ngôn ngữ nào) có nhiều bước hơn. Tất nhiên, những bước đó cũng mang lại lợi ích: bạn không thể làm điều đó (
trong C.
system.time
cuộc chiến ở các câu trả lời bắt đầu ...