Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Degraded performance for serializer retrieval for interred types when using 1.5.0 #2292

Closed
Bachemedei opened this issue May 4, 2023 · 2 comments

Comments

@Bachemedei
Copy link

Description

Retrieval of built-in serializers for inferred types is significantly slower when using Kotlinx-serialization 1.5.0 without the compiler plugin.

We have an operation which reads 1000 events from a database, iterates through the returned rows and deserializes with:

rowList.map { row ->
	val metadata: Map<String, String> = Json.decodeFromString(row.metadata)
	...
}

Below is a heatmap of the duration (ms) for otel traces for the operation described above. Between 10:25AM and 11:15AM we were running kotlinx-serialization 1.5.0 and Kotlin 1.8.0. Prior to, and after that, we were running kotlinx-serialization 1.3.3 and Kotlin 1.8.0. The duration of each operation steadily increased when using kotlinx-serialization 1.5.0.

heatmap

Example of a span during the timeframe that kotlinx-serialization 1.5.0 was being used:

v1 5 0-serialization-1 8 0-span

Benchmarks

Simple benchmarks were written to compare versions of kotlinx-serialization and Kotlin, which can be found here.

The first benchmark was designed to reproduce the issue we were experiencing:

fun retrieveSerializerPerIteration() {  
	repeat(1000) {  
		val metadata: Map<String, String> = Json.decodeFromString(json)  
	}  
}

To verify that the serializer lookup was the cause, a second benchmark was written which retrieved the serializer only once:

fun retrieveSerializerOnce() {  
	val serializer = serializer<Map<String, String>>()  
	repeat(1000) {  
		val metadata: Map<String, String> = Json.decodeFromString(serializer, json)  
	}  
}

Results (Average time per operation):

kotlin-x serialization kotlin retrieve serializater per iteration retrieve serializater once
1.5.0 1.8.0 1868.430 ms/op 1.440 ms/op
1.5.0 1.8.21 1909.756 ms/op 1.383 ms/op
1.3.3 1.8.0 2.513 ms/op 0.483 ms/op
1.3.3 1.8.21 2.594 ms/op 0.493 ms/op

The benchmarks were run again, but with the addition of the serialization compiler plugin:

kotlin-x serialization kotlin retrieve serializater per iteration retrieve serializater once
1.5.0 1.8.0 0.334 ms/op 0.356 ms/op
1.5.0 1.8.21 0.337 ms/op 0.361 ms/op
1.3.3 1.8.0 2.501 ms/op 0.490 ms/op
1.3.3 1.8.21 2.481 ms/op 0.475 ms/op

Expected behavior

Time to retrieve serializers for built in classes should be the same when using kotlinx-serialization 1.5.0/1.3.3 without the compiler plugin.

Environment

  • Kotlin version: 1.8.0 & 1.8.21
  • Library version: 1.5.0
  • Kotlin platforms: JVM
  • Gradle version: 8.1
  • Postgresql driver version: 42.4.3
  • HikariCP version: 5.0.0
@shanshin
Copy link
Contributor

shanshin commented May 4, 2023

Hi,
this performance degradation relates to #2274, fix will be released in 1.5.1

@Bachemedei
Copy link
Author

Benchmarks looking great with 1.5.1, thank you 👍

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants