1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package org.apache.commons.lang3;
19
20 import java.util.Random;
21 import java.util.concurrent.TimeUnit;
22
23 import org.openjdk.jmh.annotations.Benchmark;
24 import org.openjdk.jmh.annotations.BenchmarkMode;
25 import org.openjdk.jmh.annotations.Fork;
26 import org.openjdk.jmh.annotations.Measurement;
27 import org.openjdk.jmh.annotations.Mode;
28 import org.openjdk.jmh.annotations.OutputTimeUnit;
29 import org.openjdk.jmh.annotations.Param;
30 import org.openjdk.jmh.annotations.Scope;
31 import org.openjdk.jmh.annotations.Setup;
32 import org.openjdk.jmh.annotations.State;
33 import org.openjdk.jmh.annotations.Warmup;
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118 public class StringUtilsJoinBenchmark {
119
120 @BenchmarkMode(Mode.AverageTime)
121 @OutputTimeUnit(TimeUnit.NANOSECONDS)
122 @State(Scope.Thread)
123 @Fork(1)
124 @Warmup(iterations = WARMUP_ITERATIONS, time = WARMUP_TIME)
125 @Measurement(iterations = MEASUREMENT_ITERATIONS, time = MEASUREMENT_TIME)
126 public static class BooleanArrayBenchmark {
127
128 @Param({ "10", "100", "1000", "10000" })
129 private int size;
130 private boolean[] array;
131
132 @Setup
133 public void setup() {
134 array = new boolean[size];
135 for (int i = 0; i < array.length; i++) {
136 array[i] = i % 2 == 0;
137 }
138 }
139
140 @Benchmark
141 public String testJoinBoolean_3_20_0() {
142 return StringUtils_3_20_0.join(array, ',', 0, 10);
143 }
144
145 @Benchmark
146 public String testJoinBoolean_3_21_0() {
147 return StringUtils_3_21_0.join(array, ',', 0, 10);
148 }
149 }
150 @BenchmarkMode(Mode.AverageTime)
151 @OutputTimeUnit(TimeUnit.NANOSECONDS)
152 @State(Scope.Thread)
153 @Fork(1)
154 @Warmup(iterations = WARMUP_ITERATIONS, time = WARMUP_TIME)
155 @Measurement(iterations = MEASUREMENT_ITERATIONS, time = MEASUREMENT_TIME)
156 public static class ByteArrayBenchmark {
157
158 @Param({ "10", "100", "1000", "10000" })
159 private int size;
160 private byte[] array;
161
162 @Setup
163 public void setup() {
164 array = new byte[size];
165 final Random random = newRandom();
166 for (int i = 0; i < size; i++) {
167 array[i] = (byte) random.nextInt(Byte.MAX_VALUE);
168 }
169 }
170
171 @Benchmark
172 public String testJoinByte_3_20_0() {
173 return StringUtils_3_20_0.join(array, ',', 0, array.length);
174 }
175
176 @Benchmark
177 public String testJoinByte_3_21_0() {
178 return StringUtils_3_21_0.join(array, ',', 0, array.length);
179 }
180 }
181 @BenchmarkMode(Mode.AverageTime)
182 @OutputTimeUnit(TimeUnit.NANOSECONDS)
183 @State(Scope.Thread)
184 @Fork(1)
185 @Warmup(iterations = WARMUP_ITERATIONS, time = WARMUP_TIME)
186 @Measurement(iterations = MEASUREMENT_ITERATIONS, time = MEASUREMENT_TIME)
187 public static class CharArrayBenchmark {
188
189 @Param({ "10", "100", "1000", "10000" })
190 private int size;
191 private char[] array;
192
193 @Setup
194 public void setup() {
195 array = new char[size];
196 final Random random = newRandom();
197 for (int i = 0; i < size; i++) {
198 array[i] = (char) random.nextInt(Character.MAX_VALUE);
199 }
200 }
201
202 @Benchmark
203 public String testJoinChar_3_20_0() {
204 return StringUtils_3_20_0.join(array, ',', 0, array.length);
205 }
206
207 @Benchmark
208 public String testJoinChar_3_21_0() {
209 return StringUtils_3_21_0.join(array, ',', 0, array.length);
210 }
211 }
212 @BenchmarkMode(Mode.AverageTime)
213 @OutputTimeUnit(TimeUnit.NANOSECONDS)
214 @State(Scope.Thread)
215 @Fork(1)
216 @Warmup(iterations = WARMUP_ITERATIONS, time = WARMUP_TIME)
217 @Measurement(iterations = MEASUREMENT_ITERATIONS, time = MEASUREMENT_TIME)
218 public static class DoubleArrayBenchmark {
219
220 @Param({ "10", "100", "1000", "10000" })
221 private int size;
222 private double[] array;
223
224 @Setup
225 public void setup() {
226 array = new double[size];
227 final Random random = newRandom();
228 for (int i = 0; i < size; i++) {
229 array[i] = random.nextDouble();
230 }
231 }
232
233 @Benchmark
234 public String testJoinDouble_3_20_0() {
235 return StringUtils_3_20_0.join(array, ',', 0, array.length);
236 }
237
238 @Benchmark
239 public String testJoinDouble_3_21_0() {
240 return StringUtils_3_21_0.join(array, ',', 0, array.length);
241 }
242 }
243
244 @BenchmarkMode(Mode.AverageTime)
245 @OutputTimeUnit(TimeUnit.NANOSECONDS)
246 @State(Scope.Thread)
247 @Fork(1)
248 @Warmup(iterations = WARMUP_ITERATIONS, time = WARMUP_TIME)
249 @Measurement(iterations = MEASUREMENT_ITERATIONS, time = MEASUREMENT_TIME)
250 public static class FloatArrayBenchmark {
251
252 @Param({ "10", "100", "1000", "10000" })
253 private int size;
254 private float[] array;
255
256 @Setup
257 public void setup() {
258 array = new float[size];
259 final Random random = newRandom();
260 for (int i = 0; i < size; i++) {
261 array[i] = random.nextFloat();
262 }
263 }
264
265 @Benchmark
266 public String testJoinFloat_3_21_0() {
267 return StringUtils_3_21_0.join(array, ',', 0, array.length);
268 }
269
270 @Benchmark
271 public String testJoinFloat3_20_0() {
272 return StringUtils_3_20_0.join(array, ',', 0, array.length);
273 }
274 }
275
276 @BenchmarkMode(Mode.AverageTime)
277 @OutputTimeUnit(TimeUnit.NANOSECONDS)
278 @State(Scope.Thread)
279 @Fork(1)
280 @Warmup(iterations = WARMUP_ITERATIONS, time = WARMUP_TIME)
281 @Measurement(iterations = MEASUREMENT_ITERATIONS, time = MEASUREMENT_TIME)
282 public static class IntArrayBenchmark {
283
284 @Param({ "10", "100", "1000", "10000" })
285 private int size;
286 private int[] array;
287
288 @Setup
289 public void setup() {
290 array = new int[size];
291 final Random random = newRandom();
292 for (int i = 0; i < size; i++) {
293 array[i] = random.nextInt();
294 }
295 }
296
297 @Benchmark
298 public String testJoinInt_3_20_0() {
299 return StringUtils_3_20_0.join(array, ',', 0, array.length);
300 }
301
302 @Benchmark
303 public String testJoinInt_3_21_0() {
304 return StringUtils_3_21_0.join(array, ',', 0, array.length);
305 }
306 }
307
308 @BenchmarkMode(Mode.AverageTime)
309 @OutputTimeUnit(TimeUnit.NANOSECONDS)
310 @State(Scope.Thread)
311 @Fork(1)
312 @Warmup(iterations = WARMUP_ITERATIONS, time = WARMUP_TIME)
313 @Measurement(iterations = MEASUREMENT_ITERATIONS, time = MEASUREMENT_TIME)
314 public static class LongArrayBenchmark {
315
316 @Param({ "10", "100", "1000", "10000" })
317 private int size;
318 private long[] array;
319
320 @Setup
321 public void setup() {
322 array = new long[size];
323 final Random random = newRandom();
324 for (int i = 0; i < size; i++) {
325 array[i] = random.nextLong();
326 }
327 }
328
329 @Benchmark
330 public String testJoinLong_3_20_0() {
331 return StringUtils_3_20_0.join(array, ',', 0, array.length);
332 }
333
334 @Benchmark
335 public String testJoinLong_3_21_0() {
336 return StringUtils_3_21_0.join(array, ',', 0, array.length);
337 }
338 }
339
340 @BenchmarkMode(Mode.AverageTime)
341 @OutputTimeUnit(TimeUnit.NANOSECONDS)
342 @State(Scope.Thread)
343 @Fork(1)
344 @Warmup(iterations = WARMUP_ITERATIONS, time = WARMUP_TIME)
345 @Measurement(iterations = MEASUREMENT_ITERATIONS, time = MEASUREMENT_TIME)
346 public static class ShortArrayBenchmark {
347
348 @Param({ "10", "100", "1000", "10000" })
349 private int size;
350 private short[] array;
351
352 @Setup
353 public void setup() {
354 array = new short[size];
355 final Random random = newRandom();
356 for (int i = 0; i < size; i++) {
357 array[i] = (short) random.nextInt(Short.MAX_VALUE);
358 }
359 }
360
361 @Benchmark
362 public String testJoinShort_3_20_0() {
363 return StringUtils_3_20_0.join(array, ',', 0, array.length);
364 }
365
366 @Benchmark
367 public String testJoinShort_3_21_0() {
368 return StringUtils_3_21_0.join(array, ',', 0, array.length);
369 }
370 }
371
372 public static class StringUtils_3_20_0 {
373
374 public static final String EMPTY = "";
375
376 public static String join(final boolean[] array, final char delimiter, final int startIndex, final int endIndex) {
377 if (array == null) {
378 return null;
379 }
380 if (endIndex - startIndex <= 0) {
381 return EMPTY;
382 }
383 final StringBuilder stringBuilder = new StringBuilder(array.length * 5 + array.length - 1);
384 for (int i = startIndex; i < endIndex; i++) {
385 stringBuilder.append(array[i]).append(delimiter);
386 }
387 return stringBuilder.substring(0, stringBuilder.length() - 1);
388 }
389
390 public static String join(final byte[] array, final char delimiter, final int startIndex, final int endIndex) {
391 if (array == null) {
392 return null;
393 }
394 if (endIndex - startIndex <= 0) {
395 return EMPTY;
396 }
397 final StringBuilder stringBuilder = new StringBuilder();
398 for (int i = startIndex; i < endIndex; i++) {
399 stringBuilder.append(array[i]).append(delimiter);
400 }
401 return stringBuilder.substring(0, stringBuilder.length() - 1);
402 }
403
404 public static String join(final char[] array, final char delimiter, final int startIndex, final int endIndex) {
405 if (array == null) {
406 return null;
407 }
408 if (endIndex - startIndex <= 0) {
409 return EMPTY;
410 }
411 final StringBuilder stringBuilder = new StringBuilder(array.length * 2 - 1);
412 for (int i = startIndex; i < endIndex; i++) {
413 stringBuilder.append(array[i]).append(delimiter);
414 }
415 return stringBuilder.substring(0, stringBuilder.length() - 1);
416 }
417
418 public static String join(final double[] array, final char delimiter, final int startIndex, final int endIndex) {
419 if (array == null) {
420 return null;
421 }
422 if (endIndex - startIndex <= 0) {
423 return EMPTY;
424 }
425 final StringBuilder stringBuilder = new StringBuilder();
426 for (int i = startIndex; i < endIndex; i++) {
427 stringBuilder.append(array[i]).append(delimiter);
428 }
429 return stringBuilder.substring(0, stringBuilder.length() - 1);
430 }
431
432 public static String join(final float[] array, final char delimiter, final int startIndex, final int endIndex) {
433 if (array == null) {
434 return null;
435 }
436 if (endIndex - startIndex <= 0) {
437 return EMPTY;
438 }
439 final StringBuilder stringBuilder = new StringBuilder();
440 for (int i = startIndex; i < endIndex; i++) {
441 stringBuilder.append(array[i]).append(delimiter);
442 }
443 return stringBuilder.substring(0, stringBuilder.length() - 1);
444 }
445
446 public static String join(final int[] array, final char delimiter, final int startIndex, final int endIndex) {
447 if (array == null) {
448 return null;
449 }
450 if (endIndex - startIndex <= 0) {
451 return EMPTY;
452 }
453 final StringBuilder stringBuilder = new StringBuilder();
454 for (int i = startIndex; i < endIndex; i++) {
455 stringBuilder.append(array[i]).append(delimiter);
456 }
457 return stringBuilder.substring(0, stringBuilder.length() - 1);
458 }
459
460 public static String join(final long[] array, final char delimiter, final int startIndex, final int endIndex) {
461 if (array == null) {
462 return null;
463 }
464 if (endIndex - startIndex <= 0) {
465 return EMPTY;
466 }
467 final StringBuilder stringBuilder = new StringBuilder();
468 for (int i = startIndex; i < endIndex; i++) {
469 stringBuilder.append(array[i]).append(delimiter);
470 }
471 return stringBuilder.substring(0, stringBuilder.length() - 1);
472 }
473
474 public static String join(final short[] array, final char delimiter, final int startIndex, final int endIndex) {
475 if (array == null) {
476 return null;
477 }
478 if (endIndex - startIndex <= 0) {
479 return EMPTY;
480 }
481 final StringBuilder stringBuilder = new StringBuilder();
482 for (int i = startIndex; i < endIndex; i++) {
483 stringBuilder.append(array[i]).append(delimiter);
484 }
485 return stringBuilder.substring(0, stringBuilder.length() - 1);
486 }
487 }
488
489 public static class StringUtils_3_21_0 {
490
491 public static final String EMPTY = "";
492
493 private static StringBuilder capacity(final int count, final byte maxElementChars) {
494 return new StringBuilder(count * maxElementChars + count - 1);
495 }
496
497 public static String join(final boolean[] array, final char delimiter, final int startIndex, final int endIndex) {
498 if (array == null) {
499 return null;
500 }
501 final int count = endIndex - startIndex;
502 if (count <= 0) {
503 return EMPTY;
504 }
505 final byte maxElementChars = 5;
506 final StringBuilder stringBuilder = capacity(count, maxElementChars);
507 stringBuilder.append(array[startIndex]);
508 for (int i = startIndex + 1; i < endIndex; i++) {
509 stringBuilder.append(delimiter).append(array[i]);
510 }
511 return stringBuilder.toString();
512 }
513
514 public static String join(final byte[] array, final char delimiter, final int startIndex, final int endIndex) {
515 if (array == null) {
516 return null;
517 }
518 final int count = endIndex - startIndex;
519 if (count <= 0) {
520 return EMPTY;
521 }
522 final byte maxElementChars = 4;
523 final StringBuilder stringBuilder = capacity(count, maxElementChars);
524 stringBuilder.append(array[startIndex]);
525 for (int i = startIndex + 1; i < endIndex; i++) {
526 stringBuilder.append(delimiter).append(array[i]);
527 }
528 return stringBuilder.toString();
529 }
530
531 public static String join(final char[] array, final char delimiter, final int startIndex, final int endIndex) {
532 if (array == null) {
533 return null;
534 }
535 final int count = endIndex - startIndex;
536 if (count <= 0) {
537 return EMPTY;
538 }
539 final byte maxElementChars = 1;
540 final StringBuilder stringBuilder = capacity(count, maxElementChars);
541 stringBuilder.append(array[startIndex]);
542 for (int i = startIndex + 1; i < endIndex; i++) {
543 stringBuilder.append(delimiter).append(array[i]);
544 }
545 return stringBuilder.toString();
546 }
547
548 public static String join(final double[] array, final char delimiter, final int startIndex, final int endIndex) {
549 if (array == null) {
550 return null;
551 }
552 final int count = endIndex - startIndex;
553 if (count <= 0) {
554 return EMPTY;
555 }
556 final byte maxElementChars = 22;
557 final StringBuilder stringBuilder = capacity(count, maxElementChars);
558 stringBuilder.append(array[startIndex]);
559 for (int i = startIndex + 1; i < endIndex; i++) {
560 stringBuilder.append(delimiter).append(array[i]);
561 }
562 return stringBuilder.toString();
563 }
564
565 public static String join(final float[] array, final char delimiter, final int startIndex, final int endIndex) {
566 if (array == null) {
567 return null;
568 }
569 final int count = endIndex - startIndex;
570 if (count <= 0) {
571 return EMPTY;
572 }
573 final byte maxElementChars = 12;
574 final StringBuilder stringBuilder = capacity(count, maxElementChars);
575 stringBuilder.append(array[startIndex]);
576 for (int i = startIndex + 1; i < endIndex; i++) {
577 stringBuilder.append(delimiter).append(array[i]);
578 }
579 return stringBuilder.toString();
580 }
581
582 public static String join(final int[] array, final char delimiter, final int startIndex, final int endIndex) {
583 if (array == null) {
584 return null;
585 }
586 final int count = endIndex - startIndex;
587 if (count <= 0) {
588 return EMPTY;
589 }
590 final byte maxElementChars = 11;
591 final StringBuilder stringBuilder = capacity(count, maxElementChars);
592 stringBuilder.append(array[startIndex]);
593 for (int i = startIndex + 1; i < endIndex; i++) {
594 stringBuilder.append(delimiter).append(array[i]);
595 }
596 return stringBuilder.toString();
597 }
598
599 public static String join(final long[] array, final char delimiter, final int startIndex, final int endIndex) {
600 if (array == null) {
601 return null;
602 }
603 final int count = endIndex - startIndex;
604 if (count <= 0) {
605 return EMPTY;
606 }
607 final byte maxElementChars = 20;
608 final StringBuilder stringBuilder = capacity(count, maxElementChars);
609 stringBuilder.append(array[startIndex]);
610 for (int i = startIndex + 1; i < endIndex; i++) {
611 stringBuilder.append(delimiter).append(array[i]);
612 }
613 return stringBuilder.toString();
614 }
615
616 public static String join(final short[] array, final char delimiter, final int startIndex, final int endIndex) {
617 if (array == null) {
618 return null;
619 }
620 final int count = endIndex - startIndex;
621 if (count <= 0) {
622 return EMPTY;
623 }
624 final byte maxElementChars = 6;
625 final StringBuilder stringBuilder = capacity(count, maxElementChars);
626 stringBuilder.append(array[startIndex]);
627 for (int i = startIndex + 1; i < endIndex; i++) {
628 stringBuilder.append(delimiter).append(array[i]);
629 }
630 return stringBuilder.toString();
631 }
632 }
633
634 private static final int WARMUP_ITERATIONS = 3;
635
636 private static final int WARMUP_TIME = 1;
637
638 private static final int MEASUREMENT_ITERATIONS = 5;
639
640 private static final int MEASUREMENT_TIME = 1;
641
642 private static Random newRandom() {
643 return new Random(235);
644 }
645 }