我目前正在處理一個基準測驗問題,我愿意使用 R 的矢量化來加快計算速度,但是我真的不知道如何提高速度。非常感謝您的幫助。
function(n = 5, lower = 1, upper = 4, add = 1) {
result <- c(lower, upper)
for (i in 3:n) {
result <- append(result, result[[i - 1]] result[[i - 2]] add)
}
result
}
我的想法包括 lapply/vapply 以及某種遞回。
uj5u.com熱心網友回復:
不要append在回圈中使用。這被稱為“增長物件”,其中results物件每次迭代都會變大。眾所周知,它的效率低下,因為隨著物件變得越來越大,您的計算機必須找到越來越大的位置將其存盤在記憶體中,移動它并復制它很多。
相反,result從一開始就初始化為其全長。設定所有你不知道的值,NA并在你去的時候用值填充它們。
# original
foo = function(n = 5, lower = 1, upper = 4, add = 1) {
result <- c(lower, upper)
for (i in 3:n) {
result <- append(result, result[[i - 1]] result[[i - 2]] add)
}
result
}
foo()
bar = function(n = 5, lower = 1, upper = 4, add = 1) {
# initialize to full length
result = integer(length = n)
# set first two entries
result[1:2] <- c(lower, upper)
for (i in 3:n) {
# fill in the rest of the blanks
result[i] <- result[i - 1] result[i - 2] add
}
result
}
## same result
identical(foo(), bar())
# [1] TRUE
## about 40x faster when n = 1000 (looking at the iterations per second)
bench::mark(foo(n = 1000), bar(n = 1000))
# # A tibble: 2 × 13
# expression min median `itr/sec` mem_alloc `gc/sec` n_itr n_gc total_time result
# <bch:expr> <bch:tm> <bch:tm> <dbl> <bch:byt> <dbl> <int> <dbl> <bch:tm> <list>
# 1 foo(n = 1000) 1.73ms 1.95ms 497. 3.86MB 39.3 177 14 356ms <dbl [1…
# 2 bar(n = 1000) 51.87μs 53.46μs 18439. 11.81KB 4.13 8936 2 485ms <dbl [1…
# # … with 3 more variables: memory <list>, time <list>, gc <list>
另請注意,對于向量,您只需要單括號[。使用雙括號從類物件[[中提取單個專案。list
uj5u.com熱心網友回復:
首先,不要使用recursion,這會降低你的性能。此外,您可以使用預先分配的向量來存盤更新的值。下面是一個基準
# OP's solution
f <- function(n = 10, lower = 1, upper = 4, add = 1) {
result <- c(lower, upper)
for (i in 3:n) {
result <- append(result, result[[i - 1]] result[[i - 2]] add)
}
result
}
# A recursion implementation
f1 <- function(n = 10, lower = 1, upper = 4, add = 1) {
if (n <= 2) {
return(c(lower, upper)[1:n])
}
v <- Recall(n - 1)
c(v, sum(tail(v, 2)) add)
}
# for-loop version with pre-allocated vector
f2 <- function(n = 10, lower = 1, upper = 4, add = 1) {
v <- numeric(n)
for (i in 1:n) {
if (i <= 2) {
v[i] <- c(lower, upper)[i]
} else {
v[i] <- v[i - 1] v[i - 2] add
}
}
v
}
你會看到
> microbenchmark(f(), f1(), f2())
Unit: microseconds
expr min lq mean median uq max neval
f() 10.5 11.0 150.894 11.60 12.30 13738.9 100
f1() 68.1 69.3 170.973 70.95 82.25 6796.3 100
f2() 2.7 2.9 163.506 3.20 3.80 15966.3 100
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/497301.html
下一篇:Eclipse安裝問題
