• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2021 Google Inc. All rights reserved.
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 package com.google.flatbuffers.kotlin.benchmark
17 
18 import com.google.flatbuffers.ArrayReadWriteBuf
19 import com.google.flatbuffers.FlexBuffers
20 import com.google.flatbuffers.FlexBuffersBuilder.BUILDER_FLAG_SHARE_ALL
21 import com.google.flatbuffers.kotlin.FlexBuffersBuilder
22 import com.google.flatbuffers.kotlin.getRoot
23 import kotlinx.benchmark.Blackhole
24 import org.openjdk.jmh.annotations.Benchmark
25 import org.openjdk.jmh.annotations.BenchmarkMode
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.Scope
30 import org.openjdk.jmh.annotations.Setup
31 import org.openjdk.jmh.annotations.State
32 import java.util.concurrent.TimeUnit
33 
34 @State(Scope.Benchmark)
35 @BenchmarkMode(Mode.AverageTime)
36 @OutputTimeUnit(TimeUnit.NANOSECONDS)
37 @Measurement(iterations = 20, time = 1, timeUnit = TimeUnit.NANOSECONDS)
38 class FlexBuffersBenchmark {
39 
40   var initialCapacity = 1024
41   var value: Double = 0.0
<lambda>null42   val stringKey = Array(500) { "Ḧ̵̘́ȩ̵̐myFairlyBigKey$it" }
<lambda>null43   val stringValue = Array(500) { "Ḧ̵̘́ȩ̵̐myFairlyBigValue$it" }
<lambda>null44   val bigIntArray = IntArray(5000) { it }
45 
46   @Setup
setUpnull47   fun setUp() {
48     value = 3.0
49   }
50 
51   @Benchmark
mapKotlinnull52   fun mapKotlin(blackhole: Blackhole) {
53     val kBuilder = FlexBuffersBuilder(initialCapacity, FlexBuffersBuilder.SHARE_KEYS_AND_STRINGS)
54     kBuilder.putMap {
55       this["hello"] = "world"
56       this["int"] = 10
57       this["float"] = 12.3
58       this["intarray"] = bigIntArray
59       this.putMap("myMap") {
60         this["cool"] = "beans"
61       }
62     }
63     val ref = getRoot(kBuilder.finish())
64     val map = ref.toMap()
65     blackhole.consume(map.size)
66     blackhole.consume(map["hello"].toString())
67     blackhole.consume(map["int"].toInt())
68     blackhole.consume(map["float"].toDouble())
69     blackhole.consume(map["intarray"].toIntArray())
70     blackhole.consume(ref["myMap"]["cool"].toString())
71     blackhole.consume(ref["invalid_key"].isNull)
72   }
73 
74   @Benchmark
mapJavanull75   fun mapJava(blackhole: Blackhole) {
76     val jBuilder = com.google.flatbuffers.FlexBuffersBuilder(ArrayReadWriteBuf(initialCapacity), BUILDER_FLAG_SHARE_ALL)
77     val startMap = jBuilder.startMap()
78     jBuilder.putString("hello", "world")
79     jBuilder.putInt("int", 10)
80     jBuilder.putFloat("float", 12.3)
81 
82     val startVec = jBuilder.startVector()
83     bigIntArray.forEach { jBuilder.putInt(it) }
84     jBuilder.endVector("intarray", startVec, true, false)
85 
86     val startInnerMap = jBuilder.startMap()
87     jBuilder.putString("cool", "beans")
88     jBuilder.endMap("myMap", startInnerMap)
89 
90     jBuilder.endMap(null, startMap)
91     val ref = FlexBuffers.getRoot(jBuilder.finish())
92     val map = ref.asMap()
93     blackhole.consume(map.size())
94     blackhole.consume(map.get("hello").toString())
95     blackhole.consume(map.get("int").asInt())
96     blackhole.consume(map.get("float").asFloat())
97     val vec = map.get("intarray").asVector()
98     blackhole.consume(IntArray(vec.size()) { vec.get(it).asInt() })
99 
100     blackhole.consume(ref.asMap()["myMap"].asMap()["cool"].toString())
101     blackhole.consume(ref.asMap()["invalid_key"].isNull)
102   }
103 
104   @Benchmark
intArrayKotlinnull105   fun intArrayKotlin(blackhole: Blackhole) {
106     val kBuilder = FlexBuffersBuilder(initialCapacity, FlexBuffersBuilder.SHARE_KEYS_AND_STRINGS)
107     kBuilder.put(bigIntArray)
108     val root = getRoot(kBuilder.finish())
109     blackhole.consume(root.toIntArray())
110   }
111 
112   @Benchmark
intArrayJavanull113   fun intArrayJava(blackhole: Blackhole) {
114     val jBuilder = com.google.flatbuffers.FlexBuffersBuilder(ArrayReadWriteBuf(initialCapacity), BUILDER_FLAG_SHARE_ALL)
115     val v = jBuilder.startVector()
116     bigIntArray.forEach { jBuilder.putInt(it) }
117     jBuilder.endVector(null, v, true, false)
118     jBuilder.finish()
119     val root = FlexBuffers.getRoot(jBuilder.buffer)
120     val vec = root.asVector()
121     blackhole.consume(
122       IntArray(vec.size()) {
123         vec[it].asInt()
124       }
125     )
126   }
127 
128   @Benchmark
stringArrayKotlinnull129   fun stringArrayKotlin(blackhole: Blackhole) {
130     val kBuilder = FlexBuffersBuilder(initialCapacity, FlexBuffersBuilder.SHARE_KEYS_AND_STRINGS)
131     kBuilder.putVector { stringValue.forEach { kBuilder.put(it) } }
132     kBuilder.finish()
133     val root = getRoot(kBuilder.buffer)
134     val vec = root.toVector()
135     blackhole.consume(Array(vec.size) { vec[it].toString() })
136   }
137 
138   @Benchmark
stringArrayJavanull139   fun stringArrayJava(blackhole: Blackhole) {
140     val jBuilder = com.google.flatbuffers.FlexBuffersBuilder(ArrayReadWriteBuf(initialCapacity), BUILDER_FLAG_SHARE_ALL)
141     val v = jBuilder.startVector()
142     stringValue.forEach { jBuilder.putString(it) }
143     jBuilder.endVector(null, v, false, false)
144     jBuilder.finish()
145     val root = FlexBuffers.getRoot(jBuilder.buffer)
146     val vec = root.asVector()
147     blackhole.consume(Array(vec.size()) { vec[it].toString() })
148   }
149 
150   @Benchmark
stringMapKotlinnull151   fun stringMapKotlin(blackhole: Blackhole) {
152     val kBuilder = FlexBuffersBuilder(initialCapacity, FlexBuffersBuilder.SHARE_KEYS_AND_STRINGS)
153     val pos = kBuilder.startMap()
154     for (i in stringKey.indices) {
155       kBuilder[stringKey[i]] = stringValue[i]
156     }
157     kBuilder.endMap(pos)
158     val ref = getRoot(kBuilder.finish())
159     val map = ref.toMap()
160     val keys = map.keys
161 
162     for (key in keys) {
163       blackhole.consume(map[key.toString()].toString())
164     }
165   }
166 
167   @Benchmark
stringMapBytIndexKotlinnull168   fun stringMapBytIndexKotlin(blackhole: Blackhole) {
169     val kBuilder = FlexBuffersBuilder(initialCapacity, FlexBuffersBuilder.SHARE_KEYS_AND_STRINGS)
170     val pos = kBuilder.startMap()
171     for (i in stringKey.indices) {
172       kBuilder[stringKey[i]] = stringValue[i]
173     }
174     kBuilder.endMap(pos)
175     val ref = getRoot(kBuilder.finish())
176     val map = ref.toMap()
177     for (index in 0 until map.size) {
178       blackhole.consume(map[index].toString())
179     }
180   }
181 
182   @Benchmark
stringMapJavanull183   fun stringMapJava(blackhole: Blackhole) {
184     val jBuilder = com.google.flatbuffers.FlexBuffersBuilder(ArrayReadWriteBuf(initialCapacity), BUILDER_FLAG_SHARE_ALL)
185     val v = jBuilder.startMap()
186     for (i in stringKey.indices) {
187       jBuilder.putString(stringKey[i], stringValue[i])
188     }
189     jBuilder.endMap(null, v)
190     val ref = FlexBuffers.getRoot(jBuilder.finish())
191     val map = ref.asMap()
192     val keyVec = map.keys()
193     for (i in 0 until keyVec.size()) {
194       val s = keyVec[i].toString()
195       blackhole.consume(map[s].toString())
196     }
197   }
198 }
199