เพื่อที่จะตอบไม่ได้นี้จากจุดสุนทรียภาพ แต่ประสิทธิภาพที่มุ่งเน้นในมุมมองของฉันได้ใส่ทุกคำแนะนำข้างต้นผ่านเกณฑ์มาตรฐาน เพื่อความแม่นยำฉันได้พิจารณาข้อเสนอแนะ
x[length(x)]
mylast(x)
ซึ่งmylast
เป็นฟังก์ชั่น C ++ ที่ใช้งานผ่าน Rcpp
tail(x, n=1)
dplyr::last(x)
x[end(x)[1]]]
rev(x)[1]
และนำไปใช้กับเวกเตอร์สุ่มขนาดต่างๆ (10 ^ 3, 10 ^ 4, 10 ^ 5, 10 ^ 6 และ 10 ^ 7) ก่อนที่เราจะดูตัวเลขฉันคิดว่ามันควรชัดเจนว่าอะไรก็ตามที่ช้าลงอย่างเห็นได้ชัดด้วยขนาดอินพุตที่มากขึ้น (เช่นสิ่งที่ไม่ใช่ O (1)) ไม่ใช่ตัวเลือก นี่คือรหัสที่ฉันใช้:
Rcpp::cppFunction('double mylast(NumericVector x) { int n = x.size(); return x[n-1]; }')
options(width=100)
for (n in c(1e3,1e4,1e5,1e6,1e7)) {
x <- runif(n);
print(microbenchmark::microbenchmark(x[length(x)],
mylast(x),
tail(x, n=1),
dplyr::last(x),
x[end(x)[1]],
rev(x)[1]))}
มันทำให้ฉัน
Unit: nanoseconds
expr min lq mean median uq max neval
x[length(x)] 171 291.5 388.91 337.5 390.0 3233 100
mylast(x) 1291 1832.0 2329.11 2063.0 2276.0 19053 100
tail(x, n = 1) 7718 9589.5 11236.27 10683.0 12149.0 32711 100
dplyr::last(x) 16341 19049.5 22080.23 21673.0 23485.5 70047 100
x[end(x)[1]] 7688 10434.0 13288.05 11889.5 13166.5 78536 100
rev(x)[1] 7829 8951.5 10995.59 9883.0 10890.0 45763 100
Unit: nanoseconds
expr min lq mean median uq max neval
x[length(x)] 204 323.0 475.76 386.5 459.5 6029 100
mylast(x) 1469 2102.5 2708.50 2462.0 2995.0 9723 100
tail(x, n = 1) 7671 9504.5 12470.82 10986.5 12748.0 62320 100
dplyr::last(x) 15703 19933.5 26352.66 22469.5 25356.5 126314 100
x[end(x)[1]] 13766 18800.5 27137.17 21677.5 26207.5 95982 100
rev(x)[1] 52785 58624.0 78640.93 60213.0 72778.0 851113 100
Unit: nanoseconds
expr min lq mean median uq max neval
x[length(x)] 214 346.0 583.40 529.5 720.0 1512 100
mylast(x) 1393 2126.0 4872.60 4905.5 7338.0 9806 100
tail(x, n = 1) 8343 10384.0 19558.05 18121.0 25417.0 69608 100
dplyr::last(x) 16065 22960.0 36671.13 37212.0 48071.5 75946 100
x[end(x)[1]] 360176 404965.5 432528.84 424798.0 450996.0 710501 100
rev(x)[1] 1060547 1140149.0 1189297.38 1180997.5 1225849.0 1383479 100
Unit: nanoseconds
expr min lq mean median uq max neval
x[length(x)] 327 584.0 1150.75 996.5 1652.5 3974 100
mylast(x) 2060 3128.5 7541.51 8899.0 9958.0 16175 100
tail(x, n = 1) 10484 16936.0 30250.11 34030.0 39355.0 52689 100
dplyr::last(x) 19133 47444.5 55280.09 61205.5 66312.5 105851 100
x[end(x)[1]] 1110956 2298408.0 3670360.45 2334753.0 4475915.0 19235341 100
rev(x)[1] 6536063 7969103.0 11004418.46 9973664.5 12340089.5 28447454 100
Unit: nanoseconds
expr min lq mean median uq max neval
x[length(x)] 327 722.0 1644.16 1133.5 2055.5 13724 100
mylast(x) 1962 3727.5 9578.21 9951.5 12887.5 41773 100
tail(x, n = 1) 9829 21038.0 36623.67 43710.0 48883.0 66289 100
dplyr::last(x) 21832 35269.0 60523.40 63726.0 75539.5 200064 100
x[end(x)[1]] 21008128 23004594.5 37356132.43 30006737.0 47839917.0 105430564 100
rev(x)[1] 74317382 92985054.0 108618154.55 102328667.5 112443834.0 187925942 100
สิ่งนี้จะห้ามสิ่งที่เกี่ยวข้องrev
หรือend
เนื่องจากไม่ชัดเจนO(1)
(และการแสดงออกที่เกิดขึ้นจะถูกประเมินในแบบที่ไม่ขี้เกียจ) tail
และdplyr::last
ไม่ไกลจากการเป็นO(1)
แต่พวกเขายังช้ากว่าmylast(x)
และมากx[length(x)]
มาก เนื่องจากmylast(x)
จะช้ากว่าx[length(x)]
และให้ผลประโยชน์ไม่มี ( แต่ก็กำหนดเองและไม่ได้จัดการกับเวกเตอร์ที่ว่างเปล่าได้อย่างสง่างาม) ผมคิดว่าคำตอบเป็นที่ชัดเจน: ใช้โปรดx[length(x)]