java icon indicating copy to clipboard operation
java copied to clipboard

Kotlin encoding is 4x faster with @JsonProperty(required = true) in DYNAMIC_MODE

Open yaoligang opened this issue 5 years ago • 0 comments

Recently we did some benchmarks in Kotlin and Java. According to our benchmarks, most encoding and decoding tasks' performance are similar in Kotlin and Java. But there is a special case when using EncodingMode.DYNAMIC_MODE and @JsonProperty(required = true) together.

Environment:

  • jsoniter-0.9.23
  • javassist-3.27.0-GA
  • Java 11.0.6 + Kotlin 1.3.30
  • Windows 10

Test classes:

class KotlinRequest {
    var sessionId: String? = null
    var token: String? = null
    var operatorId: Int? = null
    var gameId: Int? = null
    var username: String? = null
    var isPromotion: Boolean? = null
    var transactionKey: String? = null
    var debit: Long = 0
    var credit: Long = 0
}

class KotlinRequestWithAnnotation {
    @JsonProperty(required = true)
    var sessionId: String? = null

    @JsonProperty(required = true)
    var token: String? = null

    @JsonProperty(required = true)
    var operatorId: Int? = null

    @JsonProperty(required = true)
    var gameId: Int? = null

    @JsonProperty(required = true)
    var username: String? = null

    @JsonProperty(required = true)
    var isPromotion: Boolean? = null

    @JsonProperty(required = true)
    var transactionKey: String? = null

    @JsonProperty(required = true)
    var debit: Long = 0

    @JsonProperty(required = true)
    var credit: Long = 0
}

Test Data:

@Benchmark
fun encodeKotlinClass(): String {
    val data = KotlinRequest()

    data.sessionId = "a285a7dcd761"
    data.token = "bad4cae6ff11a57829087fc260bfe4bd"
    data.operatorId = 10000
    data.gameId = 3
    data.username = "yourname"
    data.isPromotion = false
    data.transactionKey = "1321569482648137527"
    data.debit = 500
    data.credit = 0

    return JsonStream.serialize(data)
}

@Benchmark
fun encodeKotlinClassWithAnnotation(): String {
    val data = KotlinRequestWithAnnotation()

    data.sessionId = "a285a7dcd761"
    data.token = "bad4cae6ff11a57829087fc260bfe4bd"
    data.operatorId = 10000
    data.gameId = 3
    data.username = "yaoligang"
    data.isPromotion = false
    data.transactionKey = "1321569482648137527"
    data.debit = 500
    data.credit = 0

    return JsonStream.serialize(data)
}

Results

  • Case 1: Using EncodingMode.DYNAMIC_MODE
Benchmark                                          Mode  Cnt     Score     Error  Units
JsoniterBenchmark.encodeKotlinClass                avgt    4   922.394 ± 107.207  ns/op
JsoniterBenchmark.encodeKotlinClassWithAnnotation  avgt    4   232.835 ±  20.367  ns/op
  • Case 2: Default REFLECTION_MODE, same performance with Java codes
Benchmark                                          Mode  Cnt     Score     Error  Units
JsoniterBenchmark.encodeKotlinClass                avgt    4  2248.808 ± 121.923  ns/op
JsoniterBenchmark.encodeKotlinClassWithAnnotation  avgt    4  2184.196 ± 128.978  ns/op

You can see after using @JsonProperty(required = true) annotation, the encoding speed is about 4x faster in dynamic mode. It is over 9x faster than the default encoding in reflection mode.

I think maybe you will be interested about why Kotlin can speed up the encoding quite a lot in this case.

yaoligang avatar Apr 17 '20 10:04 yaoligang