看到許多版友在問itertools的效能,讓我想跟大家分享一些關於程式效能的經驗。
一般來說,我們不會去優化所有的程式碼,因為優化有很大的代價:一般性與可讀性。 通常跑得快與寫的快,是要做取捨的。 這裡的例子很好想像,大家只要比較R的程式碼與Rcpp的程式碼就好了。
又由於程式的效能通常也符合80-20法則: 80%的時間是花在20%的程式碼 所以實務上,我不會從頭到尾都把程式用Rcpp來寫, 而是只抽出最花時間的那段程式碼,改成Rcpp。
以一個for loop來說:
library(microbenchmark)
library(itertools)
## Loading required package: iterators
f1 <- function() {
lapply(1:100, function(i) {
lapply(1:100, function(j) {
})
})
NULL
}
f2 <- function() {
lapply(product(i = 1:100, j = 1:100), function(x) { })
NULL
}
microbenchmark(f1(), f2(), times = 10)
## Unit: milliseconds
## expr min lq mean median uq max
## f1() 4.657429 5.329925 6.092346 5.896559 6.685231 8.482395
## f2() 466.092096 485.819743 504.164424 500.838942 522.266778 538.185611
## neval
## 10
## 10
在我的電腦上,差不多是5 vs 500 milliseconds 的差異,也就是100倍。 看起來很多,可是在實務上呢?
如果每跑一次迴圈內的程式碼花1 milli seconds做計算,那整體的時間差異也是: 10000 + 5 v.s. 10000 + 500, 而在10000面前,你不太會注意到那100倍的差距。
就我自己用itertools的經驗時,通常是在寫一些不是效能很重要的程式碼。ps. 效能重要的程式碼我會用C++寫。 有時候,當寫一個只會跑若干次的程式時,為了省那不到一秒的時間,而去寫更難寫更複雜的程式碼,反而花更多時間,並且得不償失阿。 所以我在看到一些R友問效能的時候,心裡其實是感到滿訝異的: 大家是不是走火入魔了? 並不是只有跑得快才有價值,有的時候能把程式碼弄的更簡單,也是很有價值的。而這個套件的價值,偏向後者。