• 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.kotlin.ArrayReadBuffer
19 import com.google.flatbuffers.kotlin.JSONParser
20 import com.google.flatbuffers.kotlin.Reference
21 import com.google.flatbuffers.kotlin.toJson
22 import com.google.gson.Gson
23 import com.google.gson.JsonObject
24 import com.google.gson.JsonParser
25 import com.squareup.moshi.Moshi
26 import com.squareup.moshi.kotlin.reflect.KotlinJsonAdapterFactory
27 import kotlinx.benchmark.Blackhole
28 import okio.Buffer
29 import org.openjdk.jmh.annotations.Benchmark
30 import org.openjdk.jmh.annotations.BenchmarkMode
31 import org.openjdk.jmh.annotations.Measurement
32 import org.openjdk.jmh.annotations.Mode
33 import org.openjdk.jmh.annotations.OutputTimeUnit
34 import org.openjdk.jmh.annotations.Scope
35 import org.openjdk.jmh.annotations.State
36 import java.io.ByteArrayInputStream
37 import java.io.InputStreamReader
38 import java.util.concurrent.TimeUnit
39 
40 @State(Scope.Benchmark)
41 @BenchmarkMode(Mode.AverageTime)
42 @OutputTimeUnit(TimeUnit.MICROSECONDS)
43 @Measurement(iterations = 100, time = 1, timeUnit = TimeUnit.MICROSECONDS)
44 class JsonBenchmark {
45 
46   final val moshi = Moshi.Builder()
47     .addLast(KotlinJsonAdapterFactory())
48     .build()
49   final val moshiAdapter = moshi.adapter(Map::class.java)
50 
51   final val gson = Gson()
52   final val gsonParser = JsonParser()
53 
54   val fbParser = JSONParser()
55 
56   final val twitterData = this.javaClass.classLoader.getResourceAsStream("twitter.json")!!.readBytes()
57   final val canadaData = this.javaClass.classLoader.getResourceAsStream("canada.json")!!.readBytes()
58   final val citmData = this.javaClass.classLoader.getResourceAsStream("citm_catalog.json")!!.readBytes()
59 
60   val fbCitmRef = JSONParser().parse(ArrayReadBuffer(citmData))
61   val moshiCitmRef = moshi.adapter(Map::class.java).fromJson(citmData.decodeToString())
62   val gsonCitmRef = gsonParser.parse(citmData.decodeToString())
63 
readFlexBuffersnull64   fun readFlexBuffers(data: ByteArray): Reference = fbParser.parse(ArrayReadBuffer(data))
65 
66   fun readMoshi(data: ByteArray): Map<*, *>? {
67     val buffer = Buffer().write(data)
68     return moshiAdapter.fromJson(buffer)
69   }
70 
readGsonnull71   fun readGson(data: ByteArray): JsonObject {
72     val parser = JsonParser()
73     val jsonReader = InputStreamReader(ByteArrayInputStream(data))
74     return parser.parse(jsonReader).asJsonObject
75   }
76 
77   // TWITTER
78   @Benchmark
readTwitterFlexBuffersnull79   fun readTwitterFlexBuffers(hole: Blackhole? = null) = hole?.consume(readFlexBuffers(twitterData))
80   @Benchmark
81   fun readTwitterMoshi(hole: Blackhole?) = hole?.consume(readMoshi(twitterData))
82   @Benchmark
83   fun readTwitterGson(hole: Blackhole?) = hole?.consume(readGson(twitterData))
84 
85   @Benchmark
86   fun roundTripTwitterFlexBuffers(hole: Blackhole? = null) = hole?.consume(readFlexBuffers(twitterData).toJson())
87   @Benchmark
88   fun roundTripTwitterMoshi(hole: Blackhole?) = hole?.consume(moshiAdapter.toJson(readMoshi(twitterData)))
89   @Benchmark
90   fun roundTripTwitterGson(hole: Blackhole?) = hole?.consume(gson.toJson(readGson(twitterData)))
91 
92   // CITM
93   @Benchmark
94   fun readCITMFlexBuffers(hole: Blackhole? = null) = hole?.consume(readFlexBuffers(citmData))
95   @Benchmark
96   fun readCITMMoshi(hole: Blackhole?) = hole?.consume(moshiAdapter.toJson(readMoshi(citmData)))
97   @Benchmark
98   fun readCITMGson(hole: Blackhole?) = hole?.consume(gson.toJson(readGson(citmData)))
99 
100   @Benchmark
101   fun roundTripCITMFlexBuffers(hole: Blackhole? = null) = hole?.consume(readFlexBuffers(citmData).toJson())
102   @Benchmark
103   fun roundTripCITMMoshi(hole: Blackhole?) = hole?.consume(moshiAdapter.toJson(readMoshi(citmData)))
104   @Benchmark
105   fun roundTripCITMGson(hole: Blackhole?) = hole?.consume(gson.toJson(readGson(citmData)))
106 
107   @Benchmark
108   fun writeCITMFlexBuffers(hole: Blackhole? = null) = hole?.consume(fbCitmRef.toJson())
109   @Benchmark
110   fun writeCITMMoshi(hole: Blackhole?) = hole?.consume(moshiAdapter.toJson(moshiCitmRef))
111   @Benchmark
112   fun writeCITMGson(hole: Blackhole?) = hole?.consume(gson.toJson(gsonCitmRef))
113 
114   // CANADA
115   @Benchmark
116   fun readCanadaFlexBuffers(hole: Blackhole? = null) = hole?.consume(readFlexBuffers(canadaData))
117   @Benchmark
118   fun readCanadaMoshi(hole: Blackhole?) = hole?.consume(readMoshi(canadaData))
119   @Benchmark
120   fun readCanadaGson(hole: Blackhole?) = hole?.consume(readGson(canadaData))
121 }
122