memorandums

日々の生活で問題解決したこと、知ってよかったことなどを自分が思い出すために記録しています。

時間計測:javaでの配列連結

あけましておめでとうございます。。。というには遅いですが。。。一応。

あるプログラムを作っていて1024個の要素をもつfloat配列をどんどん連結していくような処理が必要になりました。

で、できれば高速に処理したかったので処理時間を計測してみました。といってもjavaではとれる方法は限られているようですが。。。

試したのはベタな方法とSystem.arraycopyを使った方法です。

■ベタな方法

class A { 
  public static void main(String [] args) {
    int c = 0;  
    float s[] = new float [10000];
    float d[] = new float [100000000];
    for (int i = 0; i < 10000; i++) {
      for (int j = 0; j < s.length; j++) {
        d[c++] = s[j];
      }   
    }   
  }
}

■System.arraycopyを使った方法

class B { 
  public static void main(String [] args) {
    float s[] = new float [10000];
    float d[] = new float [100000000];
    for (int i = 0; i < s.length; i++) {
      System.arraycopy(s, 0, d, i*s.length, s.length);
    }   
  }
}

実行結果は以下です。あんまりかわんないですね。。。javacでコンパイル時に単純ループ処理は最適化されているのでしょうか。

ベタ0.58s
System.arraycopy0.56s
(参考)java.util.Arrays + System.arraycopy5.09s

計測したのはAir Late 2010、OSX10.8.2、JDK1.7.0_06、JRE1.7.0_06でした。

ちなみに、java.util.Arraysという一見便利そうなクラスがあり、何とかこいつを利用できないかとやってみたのが「(参考)java.util.Arrays + System.arraycopy」です。java.util.Arraysは配列を生成することしかできないため、とりあえず2次元配列にセットして1次元配列にコピーしています。System.arraycopyより遅くなって当然なのですがかなり遅くなっています。一応、そのソースは以下です。

import java.util.Arrays;
class C { 
  public static void main(String [] args) {
    float s[] = new float [10000];
    float d[][] = new float [10000][10000];
    float d2[] = new float [100000000];
    for (int i = 0; i < d.length; i++) {
      d[i] = Arrays.copyOf(s, s.length);
    }   
    for (int i = 0; i < d.length; i++) {
      System.arraycopy(d[i], 0, d2, i*s.length, s.length);
    }   
  }
}

もっといい方法ないでしょうかね。。。