R3.4.0にアップデート。Rが高速に。
R3.4.0が出たと聞いた。
JITバイトコンパイラになり、loopが高速になるらしい。
適当にフィボナッチ数を計算する関数を作って試してみる。
fibonacci <- function(n){ if(n == 1) 1 else if(n == 2) 2 else (fibonacci(n-2) + fibonacci(n-1)) } fibonacci2 <- function(n){ f1 <- 1 f2 <- 2 f3 <- 1 if(n >= 3){ for(i in 3:n){ f3 <- f1 + f2 f1 <- f2 f2 <- f3 } return(f3) } return(n) } library(rbenchmark) benchmark(fibonacci(20),fibonacci2(20), replications = 100) benchmark(fibonacci2(200000), replications = 100)
#R3.3.0 > benchmark(fibonacci2(200000), replications = 100) test replications elapsed relative user.self sys.self user.child sys.child 1 fibonacci2(2e+05) 100 17.03 1 16.94 0 NA NA > benchmark(fibonacci(20),fibonacci2(20), replications = 100) test replications elapsed relative user.self sys.self user.child sys.child 1 fibonacci(20) 100 1.81 NA 1.8 0 NA NA 2 fibonacci2(20) 100 0.00 NA 0.0 0 NA NA
#R3.4.0 > benchmark(fibonacci2(200000), replications = 100) test replications elapsed relative user.self sys.self user.child sys.child 1 fibonacci2(2e+05) 100 2.25 1 2.18 0 NA NA > benchmark(fibonacci(20),fibonacci2(20), replications = 100) test replications elapsed relative user.self sys.self user.child sys.child 1 fibonacci(20) 100 0.81 NA 0.8 0 NA NA 2 fibonacci2(20) 100 0.00 NA 0.0 0 NA NA
fibonacciを見ると再帰関数も、2倍以上高速になっている。
fibonacci2をみると、for文での関数は7倍以上高速になっている。
単純に足し算でも比較
f.loop <- function(n){ x <- 0 for(i in seq_len(n)){ x <- x + 1 } return(x) } f.loop2 <- function(n){ x <- rep(1, n) y <- 0 for(i in seq_len(n)){ y <- y + x[i] } return(y) } f.vec <- function(n){ x <- rep(1, n) sum(x) } library(rbenchmark) benchmark(f.vec(100000),f.loop(100000), f.loop2(100000), replications = 1000)
#R3.3.0 > benchmark(f.vec(100000),f.loop(100000), f.loop2(100000), replications = 1000) test replications elapsed relative user.self sys.self user.child sys.child 2 f.loop(1e+05) 1000 45.19 72.887 43.75 0.14 NA NA 3 f.loop2(1e+05) 1000 67.94 109.581 65.74 0.25 NA NA 1 f.vec(1e+05) 1000 0.62 1.000 0.42 0.19 NA NA
#R.3.4.0 > benchmark(f.vec(100000),f.loop(100000), f.loop2(100000), replications = 1000) test replications elapsed relative user.self sys.self user.child sys.child 2 f.loop(1e+05) 1000 4.24 6.424 4.07 0.00 NA NA 3 f.loop2(1e+05) 1000 6.69 10.136 6.26 0.17 NA NA 1 f.vec(1e+05) 1000 0.66 1.000 0.42 0.22 NA NA
loopは10倍程度高速ですね。
ここまで高速になると良いですねぇ。他言語との絶望的な差が縮まった感じ。。
アップデート後、実際今までのコードが動かなくなったりしているので面倒だけど
(パッケージのバージョンの問題もある)、今後のことを考えてR3.4系に移行するとしよう。