[解決済み] Juliaの貧弱なR言語のサンプルを高速化する
2023-08-31 03:35:50
質問
Rとの性能比較のためのJuliaの例 は特に複雑なようです . https://github.com/JuliaLang/julia/blob/master/test/perf/perf.R
以下の2つのアルゴリズムから引き出すことのできる最速のパフォーマンスはどれくらいでしょうか(できれば、よりRらしくするために変更したことの説明付きで)。
## mandel
mandel = function(z) {
c = z
maxiter = 80
for (n in 1:maxiter) {
if (Mod(z) > 2) return(n-1)
z = z^2+c
}
return(maxiter)
}
mandelperf = function() {
re = seq(-2,0.5,.1)
im = seq(-1,1,.1)
M = matrix(0.0,nrow=length(re),ncol=length(im))
count = 1
for (r in re) {
for (i in im) {
M[count] = mandel(complex(real=r,imag=i))
count = count + 1
}
}
return(M)
}
assert(sum(mandelperf()) == 14791)
## quicksort ##
qsort_kernel = function(a, lo, hi) {
i = lo
j = hi
while (i < hi) {
pivot = a[floor((lo+hi)/2)]
while (i <= j) {
while (a[i] < pivot) i = i + 1
while (a[j] > pivot) j = j - 1
if (i <= j) {
t = a[i]
a[i] = a[j]
a[j] = t
}
i = i + 1;
j = j - 1;
}
if (lo < j) qsort_kernel(a, lo, j)
lo = i
j = hi
}
return(a)
}
qsort = function(a) {
return(qsort_kernel(a, 1, length(a)))
}
sortperf = function(n) {
v = runif(n)
return(qsort(v))
}
sortperf(5000)
どのように解決するのですか?
うーん、マンデルブローの例では、行列 M は次元が入れ替わっていますね。
M = matrix(0.0,nrow=length(im), ncol=length(re))
をインクリメントすることによって満たされるからです。
count
の連続した値)。
im
). 私の実装では、複素数のベクトルを
mandelperf.1
に作成し、インデックスとサブセットを使用してベクトルのどの要素がまだ条件を満たしていないかを追跡しながら、すべての要素に対して演算を行います。
Mod(z) <= 2
mandel.1 = function(z, maxiter=80L) {
c <- z
result <- integer(length(z))
i <- seq_along(z)
n <- 0L
while (n < maxiter && length(z)) {
j <- Mod(z) <= 2
if (!all(j)) {
result[i[!j]] <- n
i <- i[j]
z <- z[j]
c <- c[j]
}
z <- z^2 + c
n <- n + 1L
}
result[i] <- maxiter
result
}
mandelperf.1 = function() {
re = seq(-2,0.5,.1)
im = seq(-1,1,.1)
mandel.1(complex(real=rep(re, each=length(im)),
imaginary=im))
}
を使うと、13倍高速化されます(オリジナルは整数値ではなく数値を返すので、結果は同じですが同一ではありません)。
> library(rbenchmark)
> benchmark(mandelperf(), mandelperf.1(),
+ columns=c("test", "elapsed", "relative"),
+ order="relative")
test elapsed relative
2 mandelperf.1() 0.412 1.00000
1 mandelperf() 5.705 13.84709
> all.equal(sum(mandelperf()), sum(mandelperf.1()))
[1] TRUE
クイックソートの例では、実際にはソートされません。
> set.seed(123L); qsort(sample(5))
[1] 2 4 1 3 5
しかし、私の主な高速化は、ピボットの周りのパーティションをベクトル化することでした。
qsort_kernel.1 = function(a) {
if (length(a) < 2L)
return(a)
pivot <- a[floor(length(a) / 2)]
c(qsort_kernel.1(a[a < pivot]), a[a == pivot], qsort_kernel.1(a[a > pivot]))
}
qsort.1 = function(a) {
qsort_kernel.1(a)
}
sortperf.1 = function(n) {
v = runif(n)
return(qsort.1(v))
}
で、7 倍の高速化(未補正のオリジナルとの比較)。
> benchmark(sortperf(5000), sortperf.1(5000),
+ columns=c("test", "elapsed", "relative"),
+ order="relative")
test elapsed relative
2 sortperf.1(5000) 6.60 1.000000
1 sortperf(5000) 47.73 7.231818
元の比較では、JuliaはRに比べてmandelで約30倍、quicksortで500倍速いので、上記の実装はまだあまり競争力があるとは言えません。
関連
-
[解決済み] Rの%*%の意味 [重複]について
-
[解決済み] Rでcは何をするのですか?重複] [重複
-
[解決済み] ネストされた plot_grid を同じサイズに拡大縮小するには?
-
[解決済み] Rの再現性のある優れた例題の作り方
-
[解決済み] データフレームの行を複数の列でソート(並び替え)する。
-
[解決済み] Collatz予想の検証を行うC++のコードは、なぜ手書きのアセンブリよりも高速に動作するのでしょうか?
-
[解決済み] リストをデータフレームに変換する
-
[解決済み】data.table vs dplyr:一方がうまくできない、またはうまくできないことを行うことができますか?
-
[解決済み】ggplot2で軸のタイトルやラベルの大きさを変更する。
-
[解決済み】自作関数を書くときにRの省略機能を使うには?
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
R言語です。「接続を開くことができません」解決策
-
R: 環境と変数のスコープ問題
-
R - よくあるエラーとその原因 - 注意事項
-
Rのexpand.grid()コマンド
-
[解決済み] R:自然対数を使った方程式をnlsで使う
-
[解決済み] グループ化関数(tapply、by、aggregate)と*applyファミリ
-
[解決済み] 情報を損なわずに因数を整数値に変換するには?
-
[解決済み] ベクトル中のある要素のインデックスを求めるR関数はありますか?
-
[解決済み】私のggplot2構文が賢明であるときに、R CMDチェック「no visible binding for global variable」注記を処理するにはどうすればよいですか?
-
[解決済み] RとJuliaを連携させる?