• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 package kotlinx.benchmarks.json
2 
3 import com.fasterxml.jackson.databind.*
4 import com.fasterxml.jackson.module.kotlin.*
5 import kotlinx.serialization.*
6 import kotlinx.serialization.json.*
7 import kotlinx.serialization.json.okio.encodeToBufferedSink
8 import okio.blackholeSink
9 import okio.buffer
10 import org.openjdk.jmh.annotations.*
11 import java.io.ByteArrayInputStream
12 import java.io.OutputStream
13 import java.util.concurrent.*
14 
15 @Warmup(iterations = 7, time = 1)
16 @Measurement(iterations = 5, time = 1)
17 @BenchmarkMode(Mode.Throughput)
18 @OutputTimeUnit(TimeUnit.MILLISECONDS)
19 @State(Scope.Benchmark)
20 @Fork(2)
21 open class JacksonComparisonBenchmark {
22 
23     @Serializable
24     data class DefaultPixelEvent(
25         val version: Int,
26         val dateTime2: String,
27         val serverName: String,
28         val domain: String,
29         val method: String,
30         val clientIp: String,
31         val queryString: String,
32         val userAgent: String,
33         val contentType: String,
34         val browserLanguage: String,
35         val postData: String,
36         val cookies: String
37     )
38 
39     private val objectMapper: ObjectMapper = jacksonObjectMapper()
40 
41     private val data = DefaultPixelEvent(
42         version = 1,
43         dateTime2 = System.currentTimeMillis().toString(),
44         serverName = "some-endpoint-qwer",
45         domain = "some.domain.com",
46         method = "POST",
47         clientIp = "127.0.0.1",
48         queryString = "anxa=CASCative&anxv=13.901.16.34566&anxe=FoolbarActive&anxt=E7AFBF15-1761-4343-92C1-78167ED19B1C&anxtv=13.901.16.34566&anxp=%5ECQ6%5Expt292%5ES33656%5Eus&anxsi&anxd=2019-10-08T17%3A03%3A57.246Z&f=00400000&anxr=1571945992297&coid=66abafd0d49f42e58dc7536109395306&userSegment&cwsid=opgkcnbminncdgghighmimmphiooeohh",
49         userAgent = "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.14; rv:70.0) Gecko/20100101 Firefox/70.0",
50         contentType = "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8",
51         browserLanguage = "en-US,en;q=0.5",
52         postData = "-",
53         cookies = "_ga=GA1.2.971852807.1546968515"
54     )
55 
56     private val dataWithEscapes = DefaultPixelEvent(
57         version = 1,
58         dateTime2 = System.currentTimeMillis().toString(),
59         serverName = "some-endp\"oint-qwer",
60         domain = "<a href=\"some.domain.com\">",
61         method = "POST",
62         clientIp = "127.0.0.1",
63         queryString = "anxa=CASCative&anxv=13.901.16.34566&anxe=\"FoolbarActive\"&anxt=E7AFBF15-1761-4343-92C1-78167ED19B1C&anxtv=13.901.16.34566&anxp=%5ECQ6%5Expt292%5ES33656%5Eus&anxsi&anxd=2019-10-08T17%3A03%3A57.246Z&f=00400000&anxr=1571945992297&coid=\"66abafd0d49f42e58dc7536109395306\"&userSegment&cwsid=opgkcnbminncdgghighmimmphiooeohh",
64         userAgent = "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.14; rv:70.0) Gecko/20100101 Firefox/70.0",
65         contentType = "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8",
66         browserLanguage = "\"en\"-\"US\",en;\\q=0.5",
67         postData = "-",
68         cookies = "_ga=GA1.2.971852807.1546968515"
69     )
70 
71     private val devNullSink = blackholeSink().buffer()
72     private val devNullStream = object : OutputStream() {
writenull73         override fun write(b: Int) {}
writenull74         override fun write(b: ByteArray) {}
writenull75         override fun write(b: ByteArray, off: Int, len: Int) {}
76     }
77 
78     private val stringData = Json.encodeToString(DefaultPixelEvent.serializer(), data)
79     private val utf8BytesData = stringData.toByteArray()
80 
81     @Serializable
82     private class SmallDataClass(val id: Int, val name: String)
83 
84     private val smallData = SmallDataClass(42, "Vincent")
85 
86     @Benchmark
jacksonToStringnull87     fun jacksonToString(): String = objectMapper.writeValueAsString(data)
88 
89     @Benchmark
90     fun jacksonToStringWithEscapes(): String = objectMapper.writeValueAsString(dataWithEscapes)
91 
92     @Benchmark
93     fun jacksonSmallToString(): String = objectMapper.writeValueAsString(smallData)
94 
95     @Benchmark
96     fun kotlinToString(): String = Json.encodeToString(DefaultPixelEvent.serializer(), data)
97 
98     @Benchmark
99     fun kotlinToStream() = Json.encodeToStream(DefaultPixelEvent.serializer(), data, devNullStream)
100 
101     @Benchmark
102     fun kotlinFromStream() = Json.decodeFromStream(DefaultPixelEvent.serializer(), ByteArrayInputStream(utf8BytesData))
103 
104     @Benchmark
105     fun kotlinToOkio() = Json.encodeToBufferedSink(DefaultPixelEvent.serializer(), data, devNullSink)
106 
107     @Benchmark
108     fun kotlinToStringWithEscapes(): String = Json.encodeToString(DefaultPixelEvent.serializer(), dataWithEscapes)
109 
110     @Benchmark
111     fun kotlinSmallToString(): String = Json.encodeToString(SmallDataClass.serializer(), smallData)
112 
113     @Benchmark
114     fun kotlinSmallToStream() = Json.encodeToStream(SmallDataClass.serializer(), smallData, devNullStream)
115 
116     @Benchmark
117     fun kotlinSmallToOkio() = Json.encodeToBufferedSink(SmallDataClass.serializer(), smallData, devNullSink)
118 
119     @Benchmark
120     fun jacksonFromString(): DefaultPixelEvent = objectMapper.readValue(stringData, DefaultPixelEvent::class.java)
121 
122     @Benchmark
123     fun kotlinFromString(): DefaultPixelEvent = Json.decodeFromString(DefaultPixelEvent.serializer(), stringData)
124 }
125