blob: 543db5b6f0926569f469ec3bc97884f6c879f89f [file] [log] [blame]
Paul Duffin7fc0b452015-11-10 17:45:15 +00001/*
2 * Copyright (C) 2010 Google Inc.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package examples;
18
Paul Duffine2363012015-11-30 16:20:41 +000019import com.google.caliper.BeforeExperiment;
20import com.google.caliper.Benchmark;
Paul Duffin7fc0b452015-11-10 17:45:15 +000021import com.google.caliper.Param;
Paul Duffin7fc0b452015-11-10 17:45:15 +000022
23import java.util.Arrays;
24import java.util.Random;
25
26/**
27 * Tests each of four ways to copy an array, for all nine array types.
28 *
29 * <p>Once upon a time, {@code clone} was much slower than the other array copy techniques, but
30 * that was fixed in Sun bug:
31 *
32 * <a href="http://bugs.sun.com/view_bug.do?bug_id=6428387">
33 * array clone() much slower than Arrays.copyOf</a>
34 *
35 * at which time all copy methods were equally efficient.
36 *
37 * <p>Recent (2011) measurements with OpenJDK 7 on Linux are less clear. Results suggests that:
38 *
39 * <ul>
40 * <li>The different methods of copying have indistinguishable performance with hotspot server for
41 * all nine types, except that the naive LOOP is slower.
42 * With the "client" compiler, LOOP beats CLONE, which is the slowest.
43 * <li>As array sizes get large, the runtime is indeed proportional to the size of the array in
44 * memory (boolean arrays count as byte arrays!).
45 * </ul>
46 */
Paul Duffine2363012015-11-30 16:20:41 +000047public class CopyArrayBenchmark {
Paul Duffin7fc0b452015-11-10 17:45:15 +000048 public enum Strategy {
49 CLONE {
50 @Override Object[] copy(Object[] array) {
51 return array.clone();
52 }
53 @Override boolean[] copy(boolean[] array) {
54 return array.clone();
55 }
56 @Override byte[] copy(byte[] array) {
57 return array.clone();
58 }
59 @Override char[] copy(char[] array) {
60 return array.clone();
61 }
62 @Override double[] copy(double[] array) {
63 return array.clone();
64 }
65 @Override float[] copy(float[] array) {
66 return array.clone();
67 }
68 @Override int[] copy(int[] array) {
69 return array.clone();
70 }
71 @Override long[] copy(long[] array) {
72 return array.clone();
73 }
74 @Override short[] copy(short[] array) {
75 return array.clone();
76 }
77 },
78 ARRAYS_COPYOF {
79 @Override Object[] copy(Object[] array) {
80 return Arrays.copyOf(array, array.length);
81 }
82 @Override boolean[] copy(boolean[] array) {
83 return Arrays.copyOf(array, array.length);
84 }
85 @Override byte[] copy(byte[] array) {
86 return Arrays.copyOf(array, array.length);
87 }
88 @Override char[] copy(char[] array) {
89 return Arrays.copyOf(array, array.length);
90 }
91 @Override double[] copy(double[] array) {
92 return Arrays.copyOf(array, array.length);
93 }
94 @Override float[] copy(float[] array) {
95 return Arrays.copyOf(array, array.length);
96 }
97 @Override int[] copy(int[] array) {
98 return Arrays.copyOf(array, array.length);
99 }
100 @Override long[] copy(long[] array) {
101 return Arrays.copyOf(array, array.length);
102 }
103 @Override short[] copy(short[] array) {
104 return Arrays.copyOf(array, array.length);
105 }
106 },
107 SYSTEM_ARRAYCOPY {
108 @Override Object[] copy(Object[] array) {
109 Object[] copy = new Object[array.length];
110 System.arraycopy(array, 0, copy, 0, array.length);
111 return copy;
112 }
113 @Override boolean[] copy(boolean[] array) {
114 boolean[] copy = new boolean[array.length];
115 System.arraycopy(array, 0, copy, 0, array.length);
116 return copy;
117 }
118 @Override byte[] copy(byte[] array) {
119 byte[] copy = new byte[array.length];
120 System.arraycopy(array, 0, copy, 0, array.length);
121 return copy;
122 }
123 @Override char[] copy(char[] array) {
124 char[] copy = new char[array.length];
125 System.arraycopy(array, 0, copy, 0, array.length);
126 return copy;
127 }
128 @Override double[] copy(double[] array) {
129 double[] copy = new double[array.length];
130 System.arraycopy(array, 0, copy, 0, array.length);
131 return copy;
132 }
133 @Override float[] copy(float[] array) {
134 float[] copy = new float[array.length];
135 System.arraycopy(array, 0, copy, 0, array.length);
136 return copy;
137 }
138 @Override int[] copy(int[] array) {
139 int[] copy = new int[array.length];
140 System.arraycopy(array, 0, copy, 0, array.length);
141 return copy;
142 }
143 @Override long[] copy(long[] array) {
144 long[] copy = new long[array.length];
145 System.arraycopy(array, 0, copy, 0, array.length);
146 return copy;
147 }
148 @Override short[] copy(short[] array) {
149 short[] copy = new short[array.length];
150 System.arraycopy(array, 0, copy, 0, array.length);
151 return copy;
152 }
153 },
154 LOOP {
155 @Override Object[] copy(Object[] array) {
156 int len = array.length;
157 Object[] copy = new Object[len];
158 for (int i = 0; i < len; i++) {
159 copy[i] = array[i];
160 }
161 return copy;
162 }
163 @Override boolean[] copy(boolean[] array) {
164 int len = array.length;
165 boolean[] copy = new boolean[array.length];
166 for (int i = 0; i < len; i++) {
167 copy[i] = array[i];
168 }
169 return copy;
170 }
171 @Override byte[] copy(byte[] array) {
172 int len = array.length;
173 byte[] copy = new byte[array.length];
174 for (int i = 0; i < len; i++) {
175 copy[i] = array[i];
176 }
177 return copy;
178 }
179 @Override char[] copy(char[] array) {
180 int len = array.length;
181 char[] copy = new char[array.length];
182 for (int i = 0; i < len; i++) {
183 copy[i] = array[i];
184 }
185 return copy;
186 }
187 @Override double[] copy(double[] array) {
188 int len = array.length;
189 double[] copy = new double[array.length];
190 for (int i = 0; i < len; i++) {
191 copy[i] = array[i];
192 }
193 return copy;
194 }
195 @Override float[] copy(float[] array) {
196 int len = array.length;
197 float[] copy = new float[array.length];
198 for (int i = 0; i < len; i++) {
199 copy[i] = array[i];
200 }
201 return copy;
202 }
203 @Override int[] copy(int[] array) {
204 int len = array.length;
205 int[] copy = new int[array.length];
206 for (int i = 0; i < len; i++) {
207 copy[i] = array[i];
208 }
209 return copy;
210 }
211 @Override long[] copy(long[] array) {
212 int len = array.length;
213 long[] copy = new long[array.length];
214 for (int i = 0; i < len; i++) {
215 copy[i] = array[i];
216 }
217 return copy;
218 }
219 @Override short[] copy(short[] array) {
220 int len = array.length;
221 short[] copy = new short[array.length];
222 for (int i = 0; i < len; i++) {
223 copy[i] = array[i];
224 }
225 return copy;
226 }
227 },
228 ;
229
230 abstract Object[] copy(Object[] array);
231 abstract boolean[] copy(boolean[] array);
232 abstract byte[] copy(byte[] array);
233 abstract char[] copy(char[] array);
234 abstract double[] copy(double[] array);
235 abstract float[] copy(float[] array);
236 abstract int[] copy(int[] array);
237 abstract long[] copy(long[] array);
238 abstract short[] copy(short[] array);
239 }
240
241 @Param Strategy strategy;
242
243 @Param({"5", "500", "50000"}) int size;
244
245 Object[] objectArray;
246 boolean[] booleanArray;
247 byte[] byteArray;
248 char[] charArray;
249 double[] doubleArray;
250 float[] floatArray;
251 int[] intArray;
252 long[] longArray;
253 short[] shortArray;
254
Paul Duffine2363012015-11-30 16:20:41 +0000255 @BeforeExperiment void setUp() {
Paul Duffin7fc0b452015-11-10 17:45:15 +0000256 objectArray = new Object[size];
257 booleanArray = new boolean[size];
258 byteArray = new byte[size];
259 charArray = new char[size];
260 doubleArray = new double[size];
261 floatArray = new float[size];
262 intArray = new int[size];
263 longArray = new long[size];
264 shortArray = new short[size];
265
266 Random random = new Random();
267 for (int i = 0; i < size; i++) {
268 int num = random.nextInt();
269 objectArray[i] = new Object();
270 booleanArray[i] = num % 2 == 0;
271 byteArray[i] = (byte) num;
272 charArray[i] = (char) num;
273 doubleArray[i] = num;
Paul Duffine2363012015-11-30 16:20:41 +0000274 floatArray[i] = num;
Paul Duffin7fc0b452015-11-10 17:45:15 +0000275 intArray[i] = num;
276 longArray[i] = num;
277 shortArray[i] = (short) num;
278 }
279 }
280
Paul Duffine2363012015-11-30 16:20:41 +0000281 @Benchmark int objects(int reps) {
Paul Duffin7fc0b452015-11-10 17:45:15 +0000282 int dummy = 0;
283 for (int i = 0; i < reps; i++) {
Paul Duffine2363012015-11-30 16:20:41 +0000284 dummy += System.identityHashCode(strategy.copy(objectArray));
Paul Duffin7fc0b452015-11-10 17:45:15 +0000285 }
286 return dummy;
287 }
288
Paul Duffine2363012015-11-30 16:20:41 +0000289 @Benchmark int booleans(int reps) {
Paul Duffin7fc0b452015-11-10 17:45:15 +0000290 int dummy = 0;
291 for (int i = 0; i < reps; i++) {
Paul Duffine2363012015-11-30 16:20:41 +0000292 dummy += System.identityHashCode(strategy.copy(booleanArray));
Paul Duffin7fc0b452015-11-10 17:45:15 +0000293 }
294 return dummy;
295 }
296
Paul Duffine2363012015-11-30 16:20:41 +0000297 @Benchmark int bytes(int reps) {
Paul Duffin7fc0b452015-11-10 17:45:15 +0000298 int dummy = 0;
299 for (int i = 0; i < reps; i++) {
Paul Duffine2363012015-11-30 16:20:41 +0000300 dummy += System.identityHashCode(strategy.copy(byteArray));
Paul Duffin7fc0b452015-11-10 17:45:15 +0000301 }
302 return dummy;
303 }
304
Paul Duffine2363012015-11-30 16:20:41 +0000305 @Benchmark int chars(int reps) {
Paul Duffin7fc0b452015-11-10 17:45:15 +0000306 int dummy = 0;
307 for (int i = 0; i < reps; i++) {
Paul Duffine2363012015-11-30 16:20:41 +0000308 dummy += System.identityHashCode(strategy.copy(charArray));
Paul Duffin7fc0b452015-11-10 17:45:15 +0000309 }
310 return dummy;
311 }
312
Paul Duffine2363012015-11-30 16:20:41 +0000313 @Benchmark int doubles(int reps) {
Paul Duffin7fc0b452015-11-10 17:45:15 +0000314 int dummy = 0;
315 for (int i = 0; i < reps; i++) {
Paul Duffine2363012015-11-30 16:20:41 +0000316 dummy += System.identityHashCode(strategy.copy(doubleArray));
Paul Duffin7fc0b452015-11-10 17:45:15 +0000317 }
318 return dummy;
319 }
320
Paul Duffine2363012015-11-30 16:20:41 +0000321 @Benchmark int floats(int reps) {
Paul Duffin7fc0b452015-11-10 17:45:15 +0000322 int dummy = 0;
323 for (int i = 0; i < reps; i++) {
Paul Duffine2363012015-11-30 16:20:41 +0000324 dummy += System.identityHashCode(strategy.copy(floatArray));
Paul Duffin7fc0b452015-11-10 17:45:15 +0000325 }
326 return dummy;
327 }
328
Paul Duffine2363012015-11-30 16:20:41 +0000329 @Benchmark int ints(int reps) {
Paul Duffin7fc0b452015-11-10 17:45:15 +0000330 int dummy = 0;
331 for (int i = 0; i < reps; i++) {
Paul Duffine2363012015-11-30 16:20:41 +0000332 dummy += System.identityHashCode(strategy.copy(intArray));
Paul Duffin7fc0b452015-11-10 17:45:15 +0000333 }
334 return dummy;
335 }
336
Paul Duffine2363012015-11-30 16:20:41 +0000337 @Benchmark int longs(int reps) {
Paul Duffin7fc0b452015-11-10 17:45:15 +0000338 int dummy = 0;
339 for (int i = 0; i < reps; i++) {
Paul Duffine2363012015-11-30 16:20:41 +0000340 dummy += System.identityHashCode(strategy.copy(longArray));
Paul Duffin7fc0b452015-11-10 17:45:15 +0000341 }
342 return dummy;
343 }
344
Paul Duffine2363012015-11-30 16:20:41 +0000345 @Benchmark int shorts(int reps) {
Paul Duffin7fc0b452015-11-10 17:45:15 +0000346 int dummy = 0;
347 for (int i = 0; i < reps; i++) {
Paul Duffine2363012015-11-30 16:20:41 +0000348 dummy += System.identityHashCode(strategy.copy(shortArray));
Paul Duffin7fc0b452015-11-10 17:45:15 +0000349 }
350 return dummy;
351 }
Paul Duffin7fc0b452015-11-10 17:45:15 +0000352}