Skip to content

Performance Comparison: Kotlin Serialization vs Moshi #2657

Open
@ngehad

Description

@ngehad

Issue Description
This issue compares the performance of KotlinX Serialization with Moshi for JSON parsing and serialization operations. The benchmark focuses on time taken (execution time) and the number of objects allocated during the process. Benchmarking was done with Jetpack Microbenchmark, and we tested with small json response and a large one which counts approximately x21 the size of the small one.

TLDR: KotlinX serialization allocates way more objects in the memory than Moshi specially with large json response, and its execution time during serializing json is longer than Moshi.

Looking at the below table, in which we recorded our experiment results, we can see that:
1- With Small Payload (first 2 result rows): Moshi executed in slightly less time when converting from json, while kotlinx serialization executed in half the time of Moshi when converting to json. Also, the number of objects allocated in the memory was slightly higher for converting from json and equal for converting to json.
2- With Larger Response (last 2 rows): KotlinX serialization has jumped to double the execution time of Moshi when converting from json, but it performed better (time-wise) when it converted to json. On the other hand, KotlinX serialization looks to have allocated way too many objects in the memory compared to moshi for converting to json, which seems off to me. (PS. I'm aware that the number of objects allocated doesn't exactly reflect amount of memory used but my concern is about the overhead created for the garbage collector).

ktxserialization issue

Detailed results in json format: moshi results, kotlinx serialization results

Please share your thoughts if you think we're doing something wrong.

To Reproduce
Json Test data: small json, larger json

  1. Setup micro-benchmark library
  2. Add model classes for both responses here with ktx serialization annotations and here with moshi Annotations
  3. Use measureRepeated method from BenchmarkRule object in a test
    examples:
    benchmarkRule.measureRepeated { Json.decodeFromString<StResponse>(data) }
    --
    benchmarkRule.measureRepeated { Json.encodeToString(data) }
    --
    moshi = Moshi.Builder().add(KotlinJsonAdapterFactory()).build() val data = prepareStResponseJson() benchmarkRule.measureRepeated { moshi.fromJson<StResponse>(data) }
    --
    moshi = Moshi.Builder().add(KotlinJsonAdapterFactory()).build() val data = prepareStoreResponseObject() benchmarkRule.measureRepeated { moshi.toJson(data) }

Util Functions
inline fun <reified T> Moshi.toJson(data: T): String = adapter(T::class.java).toJson(data) inline fun <reified T> Moshi.fromJson(json: String): T? = adapter(T::class.java).fromJson(json)

Environment

  • Kotlin version: 1.9.22
  • Library version: 1.6.0
  • Kotlin platforms: Android (JVM)
  • Gradle version: 8.0
  • Moshi version: 1.15.1
  • Android Device: Huawei Mate 20 lite

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions