Tôi có một bản đồ được đưa ra trong bảng dưới đây:Cách nhanh nhất để phân loại dữ liệu số nguyên
Input Output
<4 0
5 0.4
6 0.5
7 0.65
8 0.75
9 0.85
>=10 1
Cho đến bây giờ, tôi đã viết 3 phiên bản:
k1 <- function(h) {
if (h <= 4) { k <- 0
} else if (h == 5) { k <- 0.4
} else if (h == 6) { k <- 0.5
} else if (h == 7) { k <- 0.65
} else if (h == 8) { k <- 0.75
} else if (h == 9) { k <- 0.85
} else if (h >= 10) { k <- 1}
return(k)
}
Thứ hai:
k2 <- function(h) {
k <- 0
k[h == 5] <- 0.4
k[h == 6] <- 0.5
k[h == 7] <- 0.65
k[h == 8] <- 0.75
k[h == 9] <- 0.85
k[h >= 10] <- 1.0
return(k)
}
Thứ ba:
k3 <- function(h) {
k <- cut(h, breaks=c(0, 5, 6, 7, 8, 9, Inf), labels=c(0, 0.5, 0.65, 0.75, 0.85, 1), right=FALSE)
return(k)
}
Tôi cần chức năng trong hai tình huống khác nhau. Đầu tiên, để đánh giá đầu vào vô hướng và thứ hai, để đánh giá một vectơ các giá trị.
Đối với đầu vào vô hướng:
h <- 5
microbenchmark(k1(h), k2(h), k3(h))
Unit: microseconds
expr min lq mean median uq max neval
k1(h) 1.208 1.5110 2.38264 1.8125 2.114 15.698 100
k2(h) 4.529 5.5855 8.71286 6.3400 7.849 73.053 100
k3(h) 52.224 54.0360 71.74953 68.9785 79.393 304.286 100
Đối với đầu vào vector:
h <- rep(5, 250)
microbenchmark(sapply(h, k1), k2(h), k3(h))
Unit: microseconds
expr min lq mean median uq max neval
sapply(h, k1) 595.592 617.327 641.8598 637.8535 654.9100 857.918 100
k2(h) 15.397 17.207 19.5470 18.1130 19.6225 49.508 100
k3(h) 110.486 116.070 131.3117 121.2020 140.6720 275.910 100
Như vậy, k1 là nhanh nhất cho đầu vào vô hướng và k2 cho đầu vào vector.
Bạn có thấy bất kỳ khả năng nào để cải thiện tốc độ không? Tôi không thể tin rằng một mã if/else vụng về như vậy sẽ nhanh nhất trong trường hợp vô hướng. Hơn nữa, tôi muốn có một chức năng thống nhất chứ không phải hai chức năng riêng biệt.
Tại sao nó ngạc nhiên khi if/else là nhanh hơn trong trường hợp vô hướng? Nó được trả về ngay lập tức sau hai lần kiểm tra và một nhiệm vụ.Có chi phí liên quan đến các hoạt động vectorization như phân bổ tập hợp con –