ลูปใน R ช้าด้วยเหตุผลเดียวกันกับภาษาใด ๆ ที่ตีความช้า: การดำเนินการทุกครั้งจะมีสัมภาระส่วนเกินจำนวนมาก
ดูR_execClosure
ในeval.c
(นี่คือฟังก์ชันที่เรียกเพื่อเรียกใช้ฟังก์ชันที่ผู้ใช้กำหนดเอง) มีความยาวเกือบ 100 บรรทัดและดำเนินการได้ทุกประเภท - สร้างสภาพแวดล้อมสำหรับการดำเนินการกำหนดอาร์กิวเมนต์ให้กับสภาพแวดล้อม ฯลฯ
ลองนึกดูว่าจะเกิดอะไรขึ้นน้อยลงเมื่อคุณเรียกใช้ฟังก์ชันใน C (กด args ไปที่ stack, jump, pop args)
นั่นคือเหตุผลที่คุณได้รับการกำหนดเวลาเช่นนี้ (ดังที่ joran ชี้ให้เห็นในความคิดเห็นมันไม่ได้เร็วจริง ๆapply
มันเป็นวง C ภายในmean
ที่กำลังเร็วapply
เป็นเพียงรหัส R เก่าปกติ):
A = matrix(as.numeric(1:100000))
ใช้ลูป: 0.342 วินาที:
system.time({
Sum = 0
for (i in seq_along(A)) {
Sum = Sum + A[[i]]
}
Sum
})
การใช้ sum: เล็กเหลือทน:
sum(A)
มันค่อนข้างอึกทึกเพราะโดยไม่มีอาการห่วงนั้นดีพอ ๆ กับsum
; ไม่มีเหตุผลในทางปฏิบัติที่ควรจะช้า เป็นเพียงการทำงานพิเศษเพิ่มเติมในแต่ละการทำซ้ำ
ดังนั้นพิจารณา:
system.time({
I = 0
while (I < 100000) {
10
I = I + 1
}
})
system.time({
I = 0
while (I < 100000) {
((((((((((10))))))))))
I = I + 1
}
})
(ตัวอย่างนั้นถูกค้นพบโดยRadford Neal )
เนื่องจาก(
ใน R เป็นตัวดำเนินการและต้องใช้การค้นหาชื่อทุกครั้งที่ใช้:
> `(` = function(x) 2
> (3)
[1] 2
หรือโดยทั่วไปการดำเนินการที่ตีความ (ในภาษาใด ๆ ) มีขั้นตอนมากกว่า แน่นอนขั้นตอนเหล่านั้นให้เกิดประโยชน์เช่นกัน: คุณไม่สามารถทำว่า(
เคล็ดลับใน C.
system.time
สงครามในคำตอบเริ่มต้น ...