irus
02/09/2021, 4:58 PMStringFormat
so it has methods like encodeToString/decodeFromString
but is somehow available direct serialization/deserialization to ByteArray?
Comparing to jackson that has writeValueAsBytes
(create string with encodeToString
and than convert to com.google.protobuf.ByteString, my case for PubSub):
Benchmark Mode Cnt Score Error Units
JsonTest.jackson thrpt 25 459596.078 ± 31782.902 ops/s
JsonTest.kotlin thrpt 25 301485.307 ± 19990.942 ops/s
irus
02/09/2021, 5:06 PMencodeToString
(vs writeValueAsString) is somehow slower:
And string mode (just Any -> String):
Benchmark Mode Cnt Score Error Units
JsonTest.jackson thrpt 5 709838.180 ± 221485.556 ops/s
JsonTest.kotlin thrpt 5 316919.843 ± 46396.238 ops/s
Marc Knaup
02/09/2021, 5:12 PMirus
02/09/2021, 5:15 PMirus
02/09/2021, 5:15 PMirus
02/09/2021, 5:16 PMirus
02/09/2021, 5:16 PMMarc Knaup
02/09/2021, 5:18 PMByteArray
or into a stream 😞
So you’ll always have an intermediate String
.Marc Knaup
02/09/2021, 5:19 PMPaul Griffith
02/09/2021, 5:29 PMJson
is defined as a StringFormat
, which is an impl of SerialFormat
, and there's an (experimental) BinaryFormat
in the same file, so it looks like there's plans for binary support in the futureirus
02/09/2021, 5:31 PMMarc Knaup
02/09/2021, 5:31 PMirus
02/09/2021, 5:32 PMMarc Knaup
02/09/2021, 5:33 PMMarc Knaup
02/09/2021, 5:34 PMMarc Knaup
02/09/2021, 5:34 PMirus
02/09/2021, 5:35 PMMarc Knaup
02/09/2021, 5:36 PM@Json
creates a codec that streams the JSON output just like kotlinx.irus
02/09/2021, 5:37 PMirus
02/09/2021, 5:47 PMirus
02/09/2021, 5:56 PMirus
02/09/2021, 6:03 PMJsonTest.baseline thrpt 10 2041713.611 ± 259978.102 ops/s
JsonTest.fluid thrpt 10 98638.922 ± 9891.324 ops/s
JsonTest.jackson thrpt 10 673197.943 ± 147790.012 ops/s
JsonTest.kotlin thrpt 10 309573.559 ± 22590.947 ops/s
Marc Knaup
02/09/2021, 6:06 PMStandardWriter.writeString
.Marc Knaup
02/09/2021, 6:06 PMirus
02/09/2021, 6:13 PMirus
02/09/2021, 6:15 PMLooking at the graph there’s some unoptimized string escaping inAlso number and depth of calls, jackson visually do less calls, and eventually just write in ByteArray.StandardWriter.writeString
Marc Knaup
02/09/2021, 6:19 PMirus
02/09/2021, 7:38 PMMarc Knaup
02/09/2021, 8:03 PMVsevolod Tolstopyatov [JB]
02/11/2021, 8:40 AMAnd string mode (just Any -> String):
Benchmark Mode Cnt Score Error Units
JsonTest.jackson thrpt 5 709838.180 ± 221485.556 ops/s
JsonTest.kotlin thrpt 5 316919.843 ± 46396.238 ops/s
This difference looks too suspicious.
Also, please ensure that you do not measuring typeOf-based serializer lookup.
E.g. Json.encodeToString(value)
is much slower than Json.encodeToString(MyValue.serializer() value)
irus
02/11/2021, 8:44 AMimport com.fasterxml.jackson.databind.ObjectMapper
import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper
import kotlinx.serialization.json.Json
import kotlinx.serialization.serializer
import org.openjdk.jmh.annotations.Benchmark
import org.openjdk.jmh.annotations.Scope
import org.openjdk.jmh.annotations.Setup
import org.openjdk.jmh.annotations.State
import org.openjdk.jmh.infra.Blackhole
@State(Scope.Benchmark)
open class JsonTest {
private lateinit var objectMapper: ObjectMapper
@Setup
open fun setup() {
objectMapper = jacksonObjectMapper()
}
@Benchmark
open fun jackson(blackhole: Blackhole) {
blackhole.consume(
objectMapper.writeValueAsString(
DefaultPixelEvent(
version = 1,
dateTime2 = System.currentTimeMillis().toString(),
serverName = "some-endpoint-qwer",
domain = "<http://some.domain.com|some.domain.com>",
method = "POST",
clientIp = "127.0.0.1",
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",
userAgent = "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.14; rv:70.0) Gecko/20100101 Firefox/70.0",
contentType = "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8",
browserLanguage = "en-US,en;q=0.5",
postData = "-",
cookies = "_ga=GA1.2.971852807.1546968515"
)
)
)
}
@Benchmark
open fun kotlin(blackhole: Blackhole) {
blackhole.consume(
Json.encodeToString(
DefaultPixelEvent.serializer(),
DefaultPixelEvent(
version = 1,
dateTime2 = System.currentTimeMillis().toString(),
serverName = "some-endpoint-qwer",
domain = "<http://some.domain.com|some.domain.com>",
method = "POST",
clientIp = "127.0.0.1",
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",
userAgent = "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.14; rv:70.0) Gecko/20100101 Firefox/70.0",
contentType = "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8",
browserLanguage = "en-US,en;q=0.5",
postData = "-",
cookies = "_ga=GA1.2.971852807.1546968515"
)
)
)
}
}
irus
02/11/2021, 8:46 AM@Serializable
data class DefaultPixelEvent(
val version: Int,
val dateTime2: String,
val serverName: String,
val domain: String,
val method: String,
val clientIp: String,
val queryString: String,
val userAgent: String,
val contentType: String,
val browserLanguage: String,
val postData: String,
val cookies: String
)