LoginSignup
2
2

More than 5 years have passed since last update.

Rのループ内でベクトルの要素を一つ一つ処理した場合の遅さを体感する

Posted at

ループ演算とベクトル演算

一般的なプログラミング言語では、次のような構文がよく使用されます。
※例:a_1 = 1, a_2 = 2, ... という数列をつくり、a_1+a_2,a_2+a_3,...という数列を計算する

コード断片(C#)
//初期化
int[] a = new a[20000];
for(int i = 0;i < 20000; i++){
    a[i] = i;
}
//計算
int[] b = new b[20000];
for(int i = 0;i < 19999; i++){
    b[i] = a[i] + a[i + 1];
}

これを、「愚直に」Rでやった場合には、次のようなソースになります。

loop.r
#初期化
df <- data.frame(a=1:20000)
#計算(aには1でアクセスできる)
for(i in 1:19999){
  df[i,2] <- df[i,1] + df[i+1,1]
}

これは結構時間がかかります。
Rでは、配列についてforなどのループを明示的に記入するよりも、ベクトル演算を駆使した方が処理が速くなります。

vector.r
#初期化
df <- data.frame(a=1:20000)
#計算
df$b <- df$a + c(df$a[2:20000],1)

ポイントは、
・ベクトル演算は同じ長さでないと行えない
・df\$aは(1列)20000行のベクトル
・df\$a[2:20000]はdf\$aの2行目の要素から20000行目の要素までのベクトル
・df\$a[2:20000]の後ろに要素を一つ追加するためにcを利用する
といったところです。

性能比較

性能の比較をするために、次のようなコードを実行してみます。

test.r
df <- data.frame(a=1:20000)
print("for loop test")
date()
for(i in 1:19999){
  df[i,2] <- df[i,1]+df[i+1,1]
}
date()
print("vector test")
df$b <- df$a + c(df$a[2:20000],1)
date()
print("test was over")
実行結果
[1] "for loop test"
[1] "Sat Oct 17 17:11:43 2015"
[1] "Sat Oct 17 17:11:45 2015"
[1] "vector test"
[1] "Sat Oct 17 17:11:45 2015"
[1] "test was over"

forでループする処理では2秒程度の処理時間がかかっていますが、vectorの場合は1秒未満であることがわかります。(core i5 4300U)
いまは20000個でテストしていますが、100000個になると、forのものは数分応答無し、vectorのものは相変わらず一瞬で応答があります。

ということで、ベクトル演算を有効活用しましょう。

2
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
2