48

可変性を減らすために、むしろ使用する必要があります

public void setValues(String[] newVals) {

     this.vals = ( newVals == null ? null : newVals.clone() );
}

また

public void setValues(String[] newVals) {

     this.vals = ( newVals == null ? null : Arrays.copyOf(newVals, newVals.length) );
}
4

4 に答える 4

44

jmhを使用して更新

jmhを使用cloneすると、わずかに良いように見えることを除いて、同様の結果が得られます。

元の投稿

パフォーマンスのクイックテストを実行しました:cloneSystem.arrayCopyおよびArrays.copyOf非常に類似したパフォーマンス(jdk 1.7.06、サーバーvm)。

詳細(ミリ秒)については、JIT後:

クローン:68
arrayCopy:68
Arrays.copyOf:68

テストコード:

public static void main(String[] args) throws InterruptedException,
        IOException {
    int sum = 0;
    int[] warmup = new int[1];
    warmup[0] = 1;
    for (int i = 0; i < 15000; i++) { // triggers JIT
        sum += copyClone(warmup);
        sum += copyArrayCopy(warmup);
        sum += copyCopyOf(warmup);
    }

    int count = 10_000_000;
    int[] array = new int[count];
    for (int i = 0; i < count; i++) {
        array[i] = i;
    }

    // additional warmup for main
    for (int i = 0; i < 10; i++) {
        sum += copyArrayCopy(array);
    }
    System.gc();
    // copyClone
    long start = System.nanoTime();
    for (int i = 0; i < 10; i++) {
        sum += copyClone(array);
    }
    long end = System.nanoTime();
    System.out.println("clone: " + (end - start) / 1000000);
    System.gc();
    // copyArrayCopy
    start = System.nanoTime();
    for (int i = 0; i < 10; i++) {
        sum += copyArrayCopy(array);
    }
    end = System.nanoTime();
    System.out.println("arrayCopy: " + (end - start) / 1000000);
    System.gc();
    // copyCopyOf
    start = System.nanoTime();
    for (int i = 0; i < 10; i++) {
        sum += copyCopyOf(array);
    }
    end = System.nanoTime();
    System.out.println("Arrays.copyOf: " + (end - start) / 1000000);
    // sum
    System.out.println(sum);
}

private static int copyClone(int[] array) {
    int[] copy = array.clone();
    return copy[copy.length - 1];
}

private static int copyArrayCopy(int[] array) {
    int[] copy = new int[array.length];
    System.arraycopy(array, 0, copy, 0, array.length);
    return copy[copy.length - 1];
}

private static int copyCopyOf(int[] array) {
    int[] copy = Arrays.copyOf(array, array.length);
    return copy[copy.length - 1];
}
于 2012-08-28T10:36:11.477 に答える
7

「clone()」使用のセキュリティも考慮してください。よく知られている攻撃のクラスは、オブジェクトの「clone()」メソッドを悪意のあるコードでオーバーライドするクラスを使用します。たとえば、CVE-2012-0507(Mac OSでの「フラッシュバック」攻撃)は、基本的に「.clone()」呼び出しを「.copyOf」呼び出しに置き換えることで対処されました。

「clone()」の廃止に関する追加の議論は、StackOverflowのここにあります:複製可能なインターフェースを実装しないオブジェクトの複製

于 2016-09-06T15:41:34.830 に答える
4

違いを確認するための簡単なプログラムを作成しました。

public static void main(String[] args) throws IOException, InterruptedException,
        PrinterException
{
  //Verify array remains immutable.

  String[] str =  {"a","b","c"};
  String[] strings  = str.clone();
  //change returned array
  strings[2]= "d";
  System.out.println(Arrays.toString(str));
  System.out.println(Arrays.toString(strings));

  String[] stringsCopy = Arrays.copyOf(str, str.length);
  stringsCopy[2]= "d";
  System.out.println(Arrays.toString(str));
  System.out.println(Arrays.toString(stringsCopy));

  //peformance
  long before = System.currentTimeMillis();
  for(int i=0;i<Integer.MAX_VALUE;i++)
  {
      str.clone();
  }
  System.out.println("Time Required for Clone: "+ (System.currentTimeMillis()-before));

  //peformance
  long beforeCopy = System.currentTimeMillis();
  for(int i=0;i<Integer.MAX_VALUE;i++)
  {
      Arrays.copyOf(str, str.length);
  }
  System.out.println("Time Required for Copy of: "+ (System.currentTimeMillis()-beforeCopy));

}

そしてそれは出力します

[a, b, c]
[a, b, d]
[a, b, c]
[a, b, d]
Time Required for Clone: 26288
Time Required for Copy of: 25413

したがって、どちらの場合String[]も不変であり、パフォーマンスはほぼ同じだと思われる場合は、Arrays.copyOf()の方が私のマシンではわずかに高速です。

アップデート

プログラムを変更して、小さな配列ではなく大きな配列[100文字列]を作成しました。

  String[] str =  new String[100];

  for(int i= 0; i<str.length;i++)
  {
      str[i]= Integer.toString(i);
  }

そして、メソッドのcopy of前にcloneメソッドを移動しました。以下の結果で。

 Time Required for Copy of: 415095
 Time Required for Clone: 428501

これもまた同じです。Please do not ask me to run the test again as it takes a while:(

アップデート2

文字列配列1000000および反復回数の場合10000

Time Required for Copy of: 32825
Time Required for Clone: 30138

copy ofより時間がかかりますclone

于 2012-08-28T10:40:23.717 に答える
1

可変性に関しては、まったく同じ、つまりデータの浅いコピーを提供します。

于 2012-08-28T10:27:01.680 に答える