/*
|
* Copyright (C) 2013 The Android Open Source Project
|
*
|
* 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 benchmarks;
|
|
import com.google.caliper.BeforeExperiment;
|
import com.google.caliper.Benchmark;
|
import com.google.caliper.Param;
|
import java.lang.reflect.Array;
|
import java.lang.reflect.Constructor;
|
import java.util.Arrays;
|
|
public class DeepArrayOpsBenchmark {
|
@Param({"0001", "0004", "0016", "0256", "2048"}) int arrayLength;
|
|
private Object[] array;
|
private Object[] array2;
|
|
@BeforeExperiment public void setUp() throws Exception {
|
array = new Object[arrayLength * 14];
|
array2 = new Object[arrayLength * 14];
|
for (int i = 0; i < arrayLength; i += 14) {
|
array[i] = new IntWrapper(i);
|
array2[i] = new IntWrapper(i);
|
|
array[i + 1] = new16ElementObjectarray();
|
array2[i + 1] = new16ElementObjectarray();
|
|
array[i + 2] = new boolean[16];
|
array2[i + 2] = new boolean[16];
|
|
array[i + 3] = new byte[16];
|
array2[i + 3] = new byte[16];
|
|
array[i + 4] = new char[16];
|
array2[i + 4] = new char[16];
|
|
array[i + 5] = new short[16];
|
array2[i + 5] = new short[16];
|
|
array[i + 6] = new float[16];
|
array2[i + 6] = new float[16];
|
|
array[i + 7] = new long[16];
|
array2[i + 7] = new long[16];
|
|
array[i + 8] = new int[16];
|
array2[i + 8] = new int[16];
|
|
array[i + 9] = new double[16];
|
array2[i + 9] = new double[16];
|
|
// Subarray types are concrete objects.
|
array[i + 10] = new16ElementArray(String.class, String.class);
|
array2[i + 10] = new16ElementArray(String.class, String.class);
|
|
array[i + 11] = new16ElementArray(Integer.class, Integer.class);
|
array2[i + 11] = new16ElementArray(Integer.class, Integer.class);
|
|
// Subarray types is an interface.
|
array[i + 12] = new16ElementArray(CharSequence.class, String.class);
|
array2[i + 12] = new16ElementArray(CharSequence.class, String.class);
|
|
array[i + 13] = null;
|
array2[i + 13] = null;
|
}
|
}
|
|
@Benchmark public void deepHashCode(int reps) {
|
for (int i = 0; i < reps; ++i) {
|
Arrays.deepHashCode(array);
|
}
|
}
|
|
@Benchmark public void deepEquals(int reps) {
|
for (int i = 0; i < reps; ++i) {
|
Arrays.deepEquals(array, array2);
|
}
|
}
|
|
private static final Object[] new16ElementObjectarray() {
|
Object[] array = new Object[16];
|
for (int i = 0; i < 16; ++i) {
|
array[i] = new IntWrapper(i);
|
}
|
|
return array;
|
}
|
|
@SuppressWarnings("unchecked")
|
private static final <T, V> T[] new16ElementArray(Class<T> arrayType, Class<V> type)
|
throws Exception {
|
T[] array = (T []) Array.newInstance(type, 16);
|
if (!arrayType.isAssignableFrom(type)) {
|
throw new IllegalArgumentException(arrayType + " is not assignable from " + type);
|
}
|
|
Constructor<V> constructor = type.getDeclaredConstructor(String.class);
|
for (int i = 0; i < 16; ++i) {
|
array[i] = (T) constructor.newInstance(String.valueOf(i + 1000));
|
}
|
|
return array;
|
}
|
|
/**
|
* A class that provides very basic equals() and hashCode() operations
|
* and doesn't resort to memoization tricks like {@link java.lang.Integer}.
|
*
|
* Useful for providing equal objects that aren't the same (a.equals(b) but
|
* a != b).
|
*/
|
public static final class IntWrapper {
|
private final int wrapped;
|
|
public IntWrapper(int wrap) {
|
wrapped = wrap;
|
}
|
|
@Override
|
public int hashCode() {
|
return wrapped;
|
}
|
|
@Override
|
public boolean equals(Object o) {
|
if (!(o instanceof IntWrapper)) {
|
return false;
|
}
|
|
return ((IntWrapper) o).wrapped == this.wrapped;
|
}
|
}
|
}
|