11package strawman .collection .mutable
22
3- import scala ._
4- import scala .collection .mutable
5- import scala .Predef ._
6-
7- import java .lang .System .nanoTime
8-
9- object ArrayDequeBenchmark extends App {
10- val candidates = Seq (
11- strawman.collection.mutable.ArrayDeque .empty[Int ],
12- scala.collection.mutable.ArrayBuffer .empty[Int ]
13- )
14-
15- def benchmark [U ](name : String , f : mutable.Buffer [Int ] => U ) = {
16- def profile (buffer : mutable.Buffer [Int ]) = {
17- val t1 = nanoTime()
18- f(buffer)
19- (nanoTime() - t1)/ 1e6
20- }
21- println(s " ===============[ $name]================= " )
22- candidates foreach (c =>
23- println(f " ${c.getClass.getSimpleName}%12s: ${profile(c)}%8.2f ms " )
24- )
25- candidates.sliding(2 ) foreach {case Seq (a, b) =>
26- assert(a == b, s " Operations are not same [ $name] for ${a.getClass.getName} and ${b.getClass.getName}" )
27- }
28- }
29-
30- val range10m = (1 to 1e7 .toInt).toArray
31-
32- benchmark(" Insert lots of items" , _ ++= range10m)
33- benchmark(" Drop some items from an head index" , _.remove(5 , 10000 ))
34- benchmark(" Drop some items from a tail index" , b => b.remove(b.length - 10000 , 10000 ))
35- benchmark(" Append lots of items one by one" , b => range10m.foreach(b.+= ))
36- benchmark(" Prepend few items one by one" , b => (1 to 1000 ).foreach(_ +=: b))
37- benchmark(" Prepend lots of items at once" , range10m ++=: _)
38- benchmark(" Insert items near head" , _.insertAll(1000 , range10m))
39- benchmark(" Reversal" , _.reverse)
40- benchmark(" Insert items near tail" , b => b.insertAll(b.size - 1000 , range10m))
41- benchmark(" Sliding" , _.sliding(size = 1000 , step = 1000 ).size)
42- benchmark(" Random indexing" , b => range10m.foreach(i => if (b.isDefinedAt(i)) b(i)))
43- benchmark(" toArray" , _.toArray)
44- benchmark(" Clear lots of items" , _.clear())
45- }
3+ import strawman .collection .arrayToArrayOps
4+
5+ import java .util .concurrent .TimeUnit
6+
7+ import org .openjdk .jmh .annotations ._
8+ import org .openjdk .jmh .infra .Blackhole
9+
10+ import scala .{Any , AnyRef , Int , Long , Unit , math }
11+ import scala .Predef .{intWrapper , $conforms }
12+
13+ @ BenchmarkMode (scala.Array (Mode .AverageTime ))
14+ @ OutputTimeUnit (TimeUnit .NANOSECONDS )
15+ @ Fork (1 )
16+ @ Warmup (iterations = 8 )
17+ @ Measurement (iterations = 8 )
18+ @ State (Scope .Benchmark )
19+ class ArrayDequeBenchmark {
20+ @ Param (scala.Array (" 0" , " 1" , " 2" , " 3" , " 4" , " 7" , " 8" , " 15" , " 16" , " 17" , " 39" , " 282" , " 4096" , " 131070" , " 7312102" ))
21+ var size : Int = _
22+
23+ var xs : ArrayDeque [Long ] = _
24+ var zs : ArrayDeque [Long ] = _
25+ var zipped : ArrayDeque [(Long , Long )] = _
26+ var randomIndices : scala.Array [Int ] = _
27+ def fresh (n : Int ) = ArrayDeque ((1 to n).map(_.toLong): _* )
28+
29+ @ Setup (Level .Trial )
30+ def initTrial (): Unit = {
31+ xs = fresh(size)
32+ zs = fresh((size / 1000 ) max 2 ).map(- _)
33+ zipped = xs.map(x => (x, x))
34+ if (size > 0 ) {
35+ randomIndices = scala.Array .fill(1000 )(scala.util.Random .nextInt(size))
36+ }
37+ }
38+
39+ @ Benchmark
40+ def create (bh : Blackhole ): Unit = bh.consume(fresh(size))
41+
42+ @ Benchmark
43+ @ OperationsPerInvocation (1000 )
44+ def expand_prepend (bh : Blackhole ): Unit = {
45+ val ys = xs
46+ var i = 0L
47+ while (i < 1000 ) {
48+ ys.prepend(i)
49+ i += 1
50+ }
51+ bh.consume(ys)
52+ }
53+
54+ @ Benchmark
55+ @ OperationsPerInvocation (1000 )
56+ def expand_prependTail (bh : Blackhole ): Unit = {
57+ var ys = xs
58+ var i = 0L
59+ while (i < 1000 ) {
60+ ys.insert(0 , i)
61+ i += 1
62+ ys = ys.tail
63+ }
64+ bh.consume(ys)
65+ }
66+
67+ @ Benchmark
68+ @ OperationsPerInvocation (1000 )
69+ def expand_append (bh : Blackhole ): Unit = {
70+ val ys = xs
71+ var i = 0L
72+ while (i < 1000 ) {
73+ ys.addOne(i)
74+ i += 1
75+ }
76+ bh.consume(ys)
77+ }
78+
79+ @ Benchmark
80+ @ OperationsPerInvocation (1000 )
81+ def expand_appendInit (bh : Blackhole ): Unit = {
82+ var ys = xs
83+ var i = 0L
84+ while (i < 1000 ) {
85+ ys.addOne(i)
86+ i += 1
87+ ys = ys.init
88+ }
89+ bh.consume(ys)
90+ }
91+
92+ @ Benchmark
93+ @ OperationsPerInvocation (1000 )
94+ def expand_prependAppend (bh : Blackhole ): Unit = {
95+ val ys = xs
96+ var i = 0L
97+ while (i < 1000 ) {
98+ if ((i & 1 ) == 1 ) ys.addOne(i)
99+ else ys.insert(0 , i)
100+ i += 1
101+ }
102+ bh.consume(ys)
103+ }
104+
105+ @ Benchmark
106+ @ OperationsPerInvocation (1000 )
107+ def expand_prependAll (bh : Blackhole ): Unit = {
108+ val ys = xs
109+ var i = 0L
110+ while (i < 1000 ) {
111+ ys.insertAll(0 , zs)
112+ i += 1
113+ }
114+ bh.consume(ys)
115+ }
116+
117+ @ Benchmark
118+ @ OperationsPerInvocation (1000 )
119+ def expand_appendAll (bh : Blackhole ): Unit = {
120+ val ys = xs
121+ var i = 0L
122+ while (i < 1000 ) {
123+ ys.addAll(zs)
124+ i += 1
125+ }
126+ bh.consume(ys)
127+ }
128+
129+ @ Benchmark
130+ @ OperationsPerInvocation (1000 )
131+ def expand_prependAllAppendAll (bh : Blackhole ): Unit = {
132+ val ys = xs
133+ var i = 0L
134+ while (i < 1000 ) {
135+ if ((i & 1 ) == 1 ) ys.addAll(zs)
136+ else ys.insertAll(0 , zs)
137+ i += 1
138+ }
139+ bh.consume(ys)
140+ }
141+
142+ @ Benchmark
143+ def expand_padTo (bh : Blackhole ): Unit = bh.consume(xs.padTo(size * 2 , 42 ))
144+
145+ @ Benchmark
146+ def traverse_foreach (bh : Blackhole ): Unit = xs.foreach(x => bh.consume(x))
147+
148+ @ Benchmark
149+ def traverse_headTail (bh : Blackhole ): Unit = {
150+ var ys = xs
151+ while (ys.nonEmpty) {
152+ bh.consume(ys.head)
153+ ys = ys.tail
154+ }
155+ }
156+
157+ @ Benchmark
158+ def traverse_initLast (bh : Blackhole ): Unit = {
159+ var ys = xs
160+ while (ys.nonEmpty) {
161+ bh.consume(ys.last)
162+ ys = ys.init
163+ }
164+ }
165+
166+ @ Benchmark
167+ def traverse_iterator (bh : Blackhole ): Unit = {
168+ val it = xs.iterator()
169+ while (it.hasNext) {
170+ bh.consume(it.next())
171+ }
172+ }
173+
174+ @ Benchmark
175+ def traverse_foldLeft (bh : Blackhole ): Unit = bh.consume(xs.foldLeft(0 ) {
176+ case (acc, n) =>
177+ bh.consume(n)
178+ acc + 1
179+ })
180+
181+ @ Benchmark
182+ def traverse_foldRight (bh : Blackhole ): Unit = bh.consume(xs.foldRight(0 ) {
183+ case (n, acc) =>
184+ bh.consume(n)
185+ acc - 1
186+ })
187+
188+ @ Benchmark
189+ @ OperationsPerInvocation (1000 )
190+ def access_last (bh : Blackhole ): Unit = {
191+ var i = 0
192+ while (i < 1000 ) {
193+ bh.consume(xs(size - 1 ))
194+ i += 1
195+ }
196+ }
197+
198+ @ Benchmark
199+ @ OperationsPerInvocation (1000 )
200+ def access_random (bh : Blackhole ): Unit = {
201+ var i = 0
202+ while (i < 1000 ) {
203+ bh.consume(xs(randomIndices(i)))
204+ i += 1
205+ }
206+ }
207+
208+ @ Benchmark
209+ def access_tail (bh : Blackhole ): Unit = bh.consume(xs.tail)
210+
211+ @ Benchmark
212+ def access_init (bh : Blackhole ): Unit = bh.consume(xs.init)
213+
214+ @ Benchmark
215+ @ OperationsPerInvocation (100 )
216+ def access_slice (bh : Blackhole ): Unit = {
217+ var i = 0
218+ while (i < 100 ) {
219+ bh.consume(xs.slice(size - size / (i + 1 ), size))
220+ i += 1
221+ }
222+ }
223+
224+ @ Benchmark
225+ @ OperationsPerInvocation (1000 )
226+ def transform_updateLast (bh : Blackhole ): Unit = {
227+ var i = 0
228+ while (i < 1000 ) {
229+ bh.consume(xs.update(size - 1 , i))
230+ i += 1
231+ }
232+ }
233+
234+ @ Benchmark
235+ @ OperationsPerInvocation (1000 )
236+ def transform_updateRandom (bh : Blackhole ): Unit = {
237+ var i = 0
238+ while (i < 1000 ) {
239+ bh.consume(xs.update(randomIndices(i), i))
240+ i += 1
241+ }
242+ }
243+
244+ @ Benchmark
245+ @ OperationsPerInvocation (100 )
246+ def transform_patch (bh : Blackhole ): Unit = {
247+ var i = 0
248+ while (i < 100 ) {
249+ val from = randomIndices(i)
250+ val replaced = randomIndices(if (i > 0 ) i - 1 else math.min(i + 1 , size - 1 ))
251+ val length = randomIndices(if (i > 1 ) i - 2 else math.min(i + 2 , size - 1 ))
252+ bh.consume(xs.patchInPlace(from, xs.take(length), replaced))
253+ i += 1
254+ }
255+ }
256+
257+ @ Benchmark
258+ def transform_distinct (bh : Blackhole ): Unit = bh.consume(xs.distinct)
259+
260+ @ Benchmark
261+ def transform_distinctBy (bh : Blackhole ): Unit = bh.consume(xs.distinctBy(_ % 2 ))
262+
263+ @ Benchmark
264+ def transform_map (bh : Blackhole ): Unit = bh.consume(xs.map(x => x + 1 ))
265+
266+ @ Benchmark
267+ @ OperationsPerInvocation (100 )
268+ def transform_span (bh : Blackhole ): Unit = {
269+ var i = 0
270+ while (i < 100 ) {
271+ val (xs1, xs2) = xs.span(x => x < randomIndices(i))
272+ bh.consume(xs1)
273+ bh.consume(xs2)
274+ i += 1
275+ }
276+ }
277+
278+ @ Benchmark
279+ def transform_zip (bh : Blackhole ): Unit = bh.consume(xs.zip(xs))
280+
281+ @ Benchmark
282+ def transform_zipMapTupled (bh : Blackhole ): Unit = {
283+ val f = (a : Long , b : Long ) => (a, b)
284+ bh.consume(xs.zip(xs).map(f.tupled))
285+ }
286+
287+ @ Benchmark
288+ def transform_zipWithIndex (bh : Blackhole ): Unit = bh.consume(xs.zipWithIndex)
289+
290+ @ Benchmark
291+ def transform_lazyZip (bh : Blackhole ): Unit = bh.consume(xs.lazyZip(xs).map((_, _)))
292+
293+ @ Benchmark
294+ def transform_unzip (bh : Blackhole ): Unit = bh.consume(zipped.unzip)
295+
296+ @ Benchmark
297+ def transform_reverse (bh : Blackhole ): Unit = bh.consume(xs.reverse)
298+
299+ @ Benchmark
300+ def transform_groupBy (bh : Blackhole ): Unit = {
301+ val result = xs.groupBy(_ % 5 )
302+ bh.consume(result)
303+ }
304+ }
0 commit comments