バージョン
- 最新(GraalVM for JDK 21)
- Devビルド
- GraalVM for JDK 21
- GraalVM for JDK 20
- GraalVM for JDK 17
- GraalVM 22.3
- GraalVM 22.2
- GraalVM 22.1
- GraalVM 22.0
- GraalVM 21.3
ランタイム・パフォーマンス
GraalVMは、長時間実行されるRコードを最適化します。Rコードのランタイム動作とGraalVMランタイムで採用されている動的コンパイルに基づく投機的最適化では、R言語のダイナミズムと複雑さによって生じる抽象化ペナルティのほとんどを排除できます。
大規模なマトリックスの相互情報量を計算する次の例のアルゴリズムを調べてみましょう:
x <- matrix(runif(1000000), 1000, 1000)
mutual_R <- function(joint_dist) {
joint_dist <- joint_dist/sum(joint_dist)
mutual_information <- 0
num_rows <- nrow(joint_dist)
num_cols <- ncol(joint_dist)
colsums <- colSums(joint_dist)
rowsums <- rowSums(joint_dist)
for(i in seq_along(1:num_rows)){
for(j in seq_along(1:num_cols)){
temp <- log((joint_dist[i,j]/(colsums[j]*rowsums[i])))
if(!is.finite(temp)){
temp = 0
}
mutual_information <-
mutual_information + joint_dist[i,j] * temp
}
}
mutual_information
}
system.time(mutual_R(x))
# user system elapsed
# 1.321 0.010 1.279
このようなアルゴリズムを効率的に実行するには、通常、C/C++コードが必要です:1
if (!require('RcppArmadillo')) {
install.packages('RcppArmadillo')
library(RcppArmadillo)
}
library(Rcpp)
sourceCpp("r_mutual.cpp")
x <- matrix(runif(1000000), 1000, 1000)
system.time(mutual_cpp(x))
# user system elapsed
# 0.037 0.003 0.040
(r_mutual.cppを使用しています。)
ただし、数回の反復の後、GraalVMではRコードを十分に効率的に実行できるため、C/C++のパフォーマンス上の利点はごくわずかです:
system.time(mutual_R(x))
# user system elapsed
# 0.063 0.001 0.077
GraalVM Rランタイムは主に、長時間実行されるアプリケーションを対象としています。したがって、ピーク・パフォーマンスは通常、ウォームアップ期間の後にのみ達成されます。Javaクラスのロードおよびコンパイルによるオーバーヘッドのため、現時点ではGNU Rよりも起動に時間がかかりますが、将来のリリースにはRのネイティブ・イメージが含まれ、起動時間が短縮されると思われます。
1 この例を初めて実行するときには、RcppArmadillo
パッケージがインストールされ、これに数分かかる場合があります。この例は、GraalVMのRランタイムとGNU Rの両方で実行できます。