blob: 543db5b6f0926569f469ec3bc97884f6c879f89f [file] [log] [blame]
/*
* Copyright (C) 2010 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package examples;
import com.google.caliper.BeforeExperiment;
import com.google.caliper.Benchmark;
import com.google.caliper.Param;
import java.util.Arrays;
import java.util.Random;
/**
* Tests each of four ways to copy an array, for all nine array types.
*
* <p>Once upon a time, {@code clone} was much slower than the other array copy techniques, but
* that was fixed in Sun bug:
*
* <a href="http://bugs.sun.com/view_bug.do?bug_id=6428387">
* array clone() much slower than Arrays.copyOf</a>
*
* at which time all copy methods were equally efficient.
*
* <p>Recent (2011) measurements with OpenJDK 7 on Linux are less clear. Results suggests that:
*
* <ul>
* <li>The different methods of copying have indistinguishable performance with hotspot server for
* all nine types, except that the naive LOOP is slower.
* With the "client" compiler, LOOP beats CLONE, which is the slowest.
* <li>As array sizes get large, the runtime is indeed proportional to the size of the array in
* memory (boolean arrays count as byte arrays!).
* </ul>
*/
public class CopyArrayBenchmark {
public enum Strategy {
CLONE {
@Override Object[] copy(Object[] array) {
return array.clone();
}
@Override boolean[] copy(boolean[] array) {
return array.clone();
}
@Override byte[] copy(byte[] array) {
return array.clone();
}
@Override char[] copy(char[] array) {
return array.clone();
}
@Override double[] copy(double[] array) {
return array.clone();
}
@Override float[] copy(float[] array) {
return array.clone();
}
@Override int[] copy(int[] array) {
return array.clone();
}
@Override long[] copy(long[] array) {
return array.clone();
}
@Override short[] copy(short[] array) {
return array.clone();
}
},
ARRAYS_COPYOF {
@Override Object[] copy(Object[] array) {
return Arrays.copyOf(array, array.length);
}
@Override boolean[] copy(boolean[] array) {
return Arrays.copyOf(array, array.length);
}
@Override byte[] copy(byte[] array) {
return Arrays.copyOf(array, array.length);
}
@Override char[] copy(char[] array) {
return Arrays.copyOf(array, array.length);
}
@Override double[] copy(double[] array) {
return Arrays.copyOf(array, array.length);
}
@Override float[] copy(float[] array) {
return Arrays.copyOf(array, array.length);
}
@Override int[] copy(int[] array) {
return Arrays.copyOf(array, array.length);
}
@Override long[] copy(long[] array) {
return Arrays.copyOf(array, array.length);
}
@Override short[] copy(short[] array) {
return Arrays.copyOf(array, array.length);
}
},
SYSTEM_ARRAYCOPY {
@Override Object[] copy(Object[] array) {
Object[] copy = new Object[array.length];
System.arraycopy(array, 0, copy, 0, array.length);
return copy;
}
@Override boolean[] copy(boolean[] array) {
boolean[] copy = new boolean[array.length];
System.arraycopy(array, 0, copy, 0, array.length);
return copy;
}
@Override byte[] copy(byte[] array) {
byte[] copy = new byte[array.length];
System.arraycopy(array, 0, copy, 0, array.length);
return copy;
}
@Override char[] copy(char[] array) {
char[] copy = new char[array.length];
System.arraycopy(array, 0, copy, 0, array.length);
return copy;
}
@Override double[] copy(double[] array) {
double[] copy = new double[array.length];
System.arraycopy(array, 0, copy, 0, array.length);
return copy;
}
@Override float[] copy(float[] array) {
float[] copy = new float[array.length];
System.arraycopy(array, 0, copy, 0, array.length);
return copy;
}
@Override int[] copy(int[] array) {
int[] copy = new int[array.length];
System.arraycopy(array, 0, copy, 0, array.length);
return copy;
}
@Override long[] copy(long[] array) {
long[] copy = new long[array.length];
System.arraycopy(array, 0, copy, 0, array.length);
return copy;
}
@Override short[] copy(short[] array) {
short[] copy = new short[array.length];
System.arraycopy(array, 0, copy, 0, array.length);
return copy;
}
},
LOOP {
@Override Object[] copy(Object[] array) {
int len = array.length;
Object[] copy = new Object[len];
for (int i = 0; i < len; i++) {
copy[i] = array[i];
}
return copy;
}
@Override boolean[] copy(boolean[] array) {
int len = array.length;
boolean[] copy = new boolean[array.length];
for (int i = 0; i < len; i++) {
copy[i] = array[i];
}
return copy;
}
@Override byte[] copy(byte[] array) {
int len = array.length;
byte[] copy = new byte[array.length];
for (int i = 0; i < len; i++) {
copy[i] = array[i];
}
return copy;
}
@Override char[] copy(char[] array) {
int len = array.length;
char[] copy = new char[array.length];
for (int i = 0; i < len; i++) {
copy[i] = array[i];
}
return copy;
}
@Override double[] copy(double[] array) {
int len = array.length;
double[] copy = new double[array.length];
for (int i = 0; i < len; i++) {
copy[i] = array[i];
}
return copy;
}
@Override float[] copy(float[] array) {
int len = array.length;
float[] copy = new float[array.length];
for (int i = 0; i < len; i++) {
copy[i] = array[i];
}
return copy;
}
@Override int[] copy(int[] array) {
int len = array.length;
int[] copy = new int[array.length];
for (int i = 0; i < len; i++) {
copy[i] = array[i];
}
return copy;
}
@Override long[] copy(long[] array) {
int len = array.length;
long[] copy = new long[array.length];
for (int i = 0; i < len; i++) {
copy[i] = array[i];
}
return copy;
}
@Override short[] copy(short[] array) {
int len = array.length;
short[] copy = new short[array.length];
for (int i = 0; i < len; i++) {
copy[i] = array[i];
}
return copy;
}
},
;
abstract Object[] copy(Object[] array);
abstract boolean[] copy(boolean[] array);
abstract byte[] copy(byte[] array);
abstract char[] copy(char[] array);
abstract double[] copy(double[] array);
abstract float[] copy(float[] array);
abstract int[] copy(int[] array);
abstract long[] copy(long[] array);
abstract short[] copy(short[] array);
}
@Param Strategy strategy;
@Param({"5", "500", "50000"}) int size;
Object[] objectArray;
boolean[] booleanArray;
byte[] byteArray;
char[] charArray;
double[] doubleArray;
float[] floatArray;
int[] intArray;
long[] longArray;
short[] shortArray;
@BeforeExperiment void setUp() {
objectArray = new Object[size];
booleanArray = new boolean[size];
byteArray = new byte[size];
charArray = new char[size];
doubleArray = new double[size];
floatArray = new float[size];
intArray = new int[size];
longArray = new long[size];
shortArray = new short[size];
Random random = new Random();
for (int i = 0; i < size; i++) {
int num = random.nextInt();
objectArray[i] = new Object();
booleanArray[i] = num % 2 == 0;
byteArray[i] = (byte) num;
charArray[i] = (char) num;
doubleArray[i] = num;
floatArray[i] = num;
intArray[i] = num;
longArray[i] = num;
shortArray[i] = (short) num;
}
}
@Benchmark int objects(int reps) {
int dummy = 0;
for (int i = 0; i < reps; i++) {
dummy += System.identityHashCode(strategy.copy(objectArray));
}
return dummy;
}
@Benchmark int booleans(int reps) {
int dummy = 0;
for (int i = 0; i < reps; i++) {
dummy += System.identityHashCode(strategy.copy(booleanArray));
}
return dummy;
}
@Benchmark int bytes(int reps) {
int dummy = 0;
for (int i = 0; i < reps; i++) {
dummy += System.identityHashCode(strategy.copy(byteArray));
}
return dummy;
}
@Benchmark int chars(int reps) {
int dummy = 0;
for (int i = 0; i < reps; i++) {
dummy += System.identityHashCode(strategy.copy(charArray));
}
return dummy;
}
@Benchmark int doubles(int reps) {
int dummy = 0;
for (int i = 0; i < reps; i++) {
dummy += System.identityHashCode(strategy.copy(doubleArray));
}
return dummy;
}
@Benchmark int floats(int reps) {
int dummy = 0;
for (int i = 0; i < reps; i++) {
dummy += System.identityHashCode(strategy.copy(floatArray));
}
return dummy;
}
@Benchmark int ints(int reps) {
int dummy = 0;
for (int i = 0; i < reps; i++) {
dummy += System.identityHashCode(strategy.copy(intArray));
}
return dummy;
}
@Benchmark int longs(int reps) {
int dummy = 0;
for (int i = 0; i < reps; i++) {
dummy += System.identityHashCode(strategy.copy(longArray));
}
return dummy;
}
@Benchmark int shorts(int reps) {
int dummy = 0;
for (int i = 0; i < reps; i++) {
dummy += System.identityHashCode(strategy.copy(shortArray));
}
return dummy;
}
}