2
* Copyright 2014 Goldman Sachs.
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
8
* http://www.apache.org/licenses/LICENSE-2.0
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.
17
package com.gs.collections.impl.jmh;
19
import java.util.ArrayList;
20
import java.util.List;
21
import java.util.concurrent.ExecutorService;
22
import java.util.concurrent.Executors;
23
import java.util.concurrent.TimeUnit;
25
import com.gs.collections.impl.block.factory.Procedures;
26
import com.gs.collections.impl.block.procedure.CountProcedure;
27
import com.gs.collections.impl.list.Interval;
28
import com.gs.collections.impl.list.mutable.FastList;
29
import com.gs.collections.impl.parallel.ParallelIterate;
30
import org.junit.Assert;
31
import org.openjdk.jmh.annotations.BenchmarkMode;
32
import org.openjdk.jmh.annotations.GenerateMicroBenchmark;
33
import org.openjdk.jmh.annotations.Level;
34
import org.openjdk.jmh.annotations.Measurement;
35
import org.openjdk.jmh.annotations.Mode;
36
import org.openjdk.jmh.annotations.OutputTimeUnit;
37
import org.openjdk.jmh.annotations.Param;
38
import org.openjdk.jmh.annotations.Scope;
39
import org.openjdk.jmh.annotations.Setup;
40
import org.openjdk.jmh.annotations.State;
41
import org.openjdk.jmh.annotations.TearDown;
42
import org.openjdk.jmh.annotations.Warmup;
45
@BenchmarkMode(Mode.Throughput)
46
@OutputTimeUnit(TimeUnit.SECONDS)
47
public class CountTest
49
private static final int SIZE = 1_000_000;
50
private static final int BATCH_SIZE = 10_000;
51
private final List<Integer> integersJDK = new ArrayList<>(Interval.oneTo(SIZE));
52
private final FastList<Integer> integersGSC = new FastList<>(Interval.oneTo(SIZE));
54
private ExecutorService executorService;
56
@Param({"0", "1", "2", "3"})
57
public int megamorphicWarmupLevel;
62
this.executorService = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors());
66
public void tearDown() throws InterruptedException
68
this.executorService.shutdownNow();
69
this.executorService.awaitTermination(1L, TimeUnit.SECONDS);
73
public void setUp_megamorphic()
75
if (this.megamorphicWarmupLevel > 0)
79
long evens = this.integersJDK.stream().filter(each -> each % 2 == 0).count();
80
Assert.assertEquals(SIZE / 2, evens);
81
long odds = this.integersJDK.stream().filter(each -> each % 2 == 1).count();
82
Assert.assertEquals(SIZE / 2, odds);
83
long evens2 = this.integersJDK.stream().filter(each -> (each & 1) == 0).count();
84
Assert.assertEquals(SIZE / 2, evens2);
87
// parallel, lazy, JDK
89
long evens = this.integersJDK.parallelStream().filter(each -> each % 2 == 0).count();
90
Assert.assertEquals(SIZE / 2, evens);
91
long odds = this.integersJDK.parallelStream().filter(each -> each % 2 == 1).count();
92
Assert.assertEquals(SIZE / 2, odds);
93
long evens2 = this.integersJDK.parallelStream().filter(each -> (each & 1) == 0).count();
94
Assert.assertEquals(SIZE / 2, evens2);
99
long evens = this.integersGSC.asLazy().count(each -> each % 2 == 0);
100
Assert.assertEquals(SIZE / 2, evens);
101
long odds = this.integersGSC.asLazy().count(each -> each % 2 == 1);
102
Assert.assertEquals(SIZE / 2, odds);
103
long evens2 = this.integersGSC.asLazy().count(each -> (each & 1) == 0);
104
Assert.assertEquals(SIZE / 2, evens2);
107
// parallel, lazy, GSC
109
long evens = this.integersGSC.asParallel(this.executorService, BATCH_SIZE).count(each -> each % 2 == 0);
110
Assert.assertEquals(SIZE / 2, evens);
111
long odds = this.integersGSC.asParallel(this.executorService, BATCH_SIZE).count(each -> each % 2 == 1);
112
Assert.assertEquals(SIZE / 2, odds);
113
long evens2 = this.integersGSC.asParallel(this.executorService, BATCH_SIZE).count(each -> (each & 1) == 0);
114
Assert.assertEquals(SIZE / 2, evens2);
117
// serial, eager, GSC
119
long evens = this.integersGSC.count(each -> each % 2 == 0);
120
Assert.assertEquals(SIZE / 2, evens);
121
long odds = this.integersGSC.count(each -> each % 2 == 1);
122
Assert.assertEquals(SIZE / 2, odds);
123
long evens2 = this.integersGSC.count(each -> (each & 1) == 0);
124
Assert.assertEquals(SIZE / 2, evens2);
127
// parallel, eager, GSC
128
long evens = ParallelIterate.count(this.integersGSC, each -> each % 2 == 0);
129
Assert.assertEquals(SIZE / 2, evens);
130
long odds = ParallelIterate.count(this.integersGSC, each -> each % 2 == 1);
131
Assert.assertEquals(SIZE / 2, odds);
132
long evens2 = ParallelIterate.count(this.integersGSC, each -> (each & 1) == 0);
133
Assert.assertEquals(SIZE / 2, evens2);
136
if (this.megamorphicWarmupLevel > 1)
138
// stream().mapToLong().reduce()
141
this.integersJDK.stream().mapToLong(each -> each + 1).reduce(0, (accum, each) -> accum + each));
145
this.integersJDK.stream().mapToLong(each -> each + 2).reduce(0, (accum, each) -> {
146
Assert.assertTrue(each >= 0);
153
this.integersJDK.stream().mapToLong(each -> each + 3).reduce(0, (accum, each) -> {
154
long result = accum + each;
155
Assert.assertTrue(each >= 0);
160
// parallelStream().mapToLong().reduce()
163
this.integersJDK.parallelStream().mapToLong(each -> each + 1).reduce(0, (accum, each) -> accum + each));
167
this.integersJDK.parallelStream().mapToLong(each -> each + 2).reduce(0, (accum, each) -> {
168
Assert.assertTrue(each >= 0);
175
this.integersJDK.parallelStream().mapToLong(each -> each + 3).reduce(0, (accum, each) -> {
176
long result = accum + each;
177
Assert.assertTrue(each >= 0);
183
if (this.megamorphicWarmupLevel > 2)
185
this.integersGSC.asLazy().forEach(Procedures.cast(Assert::assertNotNull));
186
this.integersGSC.asLazy().forEach(Procedures.cast(each -> Assert.assertEquals(each, each)));
187
this.integersGSC.asLazy().forEach(new CountProcedure<>());
189
this.integersGSC.asParallel(this.executorService, BATCH_SIZE).forEach(Assert::assertNotNull);
190
this.integersGSC.asParallel(this.executorService, BATCH_SIZE).forEach(each -> Assert.assertEquals(each, each));
191
this.integersGSC.asParallel(this.executorService, BATCH_SIZE).forEach(new CountProcedure<>());
193
this.integersJDK.stream().forEach(Assert::assertNotNull);
194
this.integersJDK.stream().forEach(each -> Assert.assertEquals(each, each));
196
this.integersJDK.parallelStream().forEach(Assert::assertNotNull);
197
this.integersJDK.parallelStream().forEach(each -> Assert.assertEquals(each, each));
200
CountScalaTest.megamorphic(this.megamorphicWarmupLevel);
203
@Warmup(iterations = 20)
204
@Measurement(iterations = 10)
205
@GenerateMicroBenchmark
206
public void serial_lazy_jdk()
208
long evens = this.integersJDK.stream().filter(each -> each % 2 == 0).count();
209
Assert.assertEquals(SIZE / 2, evens);
212
@Warmup(iterations = 50)
213
@Measurement(iterations = 25)
214
@GenerateMicroBenchmark
215
public void parallel_lazy_jdk()
217
long evens = this.integersJDK.parallelStream().filter(each -> each % 2 == 0).count();
218
Assert.assertEquals(SIZE / 2, evens);
221
@Warmup(iterations = 20)
222
@Measurement(iterations = 10)
223
@GenerateMicroBenchmark
224
public void serial_eager_gsc()
226
int evens = this.integersGSC.count(each -> each % 2 == 0);
227
Assert.assertEquals(SIZE / 2, evens);
230
@Warmup(iterations = 20)
231
@Measurement(iterations = 10)
232
@GenerateMicroBenchmark
233
public void serial_lazy_gsc()
235
int evens = this.integersGSC.asLazy().count(each -> each % 2 == 0);
236
Assert.assertEquals(SIZE / 2, evens);
239
@Warmup(iterations = 50)
240
@Measurement(iterations = 25)
241
@GenerateMicroBenchmark
242
public void parallel_eager_gsc()
244
int evens = ParallelIterate.count(this.integersGSC, each -> each % 2 == 0, BATCH_SIZE, this.executorService);
245
Assert.assertEquals(SIZE / 2, evens);
248
@Warmup(iterations = 50)
249
@Measurement(iterations = 25)
250
@GenerateMicroBenchmark
251
public void parallel_lazy_gsc()
253
int evens = this.integersGSC.asParallel(this.executorService, BATCH_SIZE).count(each -> each % 2 == 0);
254
Assert.assertEquals(SIZE / 2, evens);
257
@Warmup(iterations = 20)
258
@Measurement(iterations = 10)
259
@GenerateMicroBenchmark
260
public void serial_eager_scala()
262
CountScalaTest.serial_eager_scala();
265
@Warmup(iterations = 20)
266
@Measurement(iterations = 10)
267
@GenerateMicroBenchmark
268
public void serial_lazy_scala()
270
CountScalaTest.serial_lazy_scala();
273
@Warmup(iterations = 50)
274
@Measurement(iterations = 25)
275
@GenerateMicroBenchmark
276
public void parallel_lazy_scala()
278
CountScalaTest.parallel_lazy_scala();