-
Notifications
You must be signed in to change notification settings - Fork 636
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
Performance Comparison: Kotlin Serialization vs Moshi #2657
Comments
Hi! Thanks for the detailed report, I appreciate it. I have a couple of questions to clarify:
|
Hi! Thanks for the prompt response.
|
Okay, it's just that usually everyone uses those terms in an opposite way, i.e. parsing is a process of consuming json and producing data object, that's why I got confused :) |
Definitely interested in how you are invoking the libraries. Moshi, for example, is optimized for reading to and from UTF-8 bytes in a streaming fashion with Okio. If you are using java.io, or using Strings as your source or destination, the benchmark now includes UTF-8 encoding and decoding as well as forced byte array copies. This library also has many modes in which it can be invoked, and the most performant is usually when targeting a string. Streaming is generally slower, but if you want to do apples-to-apples maybe that's what you want. It may be beneficial having separate benchmark modes where you change the destination from bytes to strings in both libraries and compare, and then ultimately compare the best mode of both. Libraries like Retrofit can actually choose the most performant mode of each library, for example, but others might be interested in the same-mode comparisons where something like streaming is required. |
Oh, my bad! I updated the description to avoid the confusion. |
Thanks for the comment! You're absolutely right, the current benchmark might be influenced by the data format used, since I'm using JSON data in string format for testing. I'm open to setting up a separate benchmark mode for byte data. But I'm really still curious where this difference came from since I used the string format in both tests. |
@sandwwraith Hello, hope you've been doin' well. I was wondering if we have an update on this issue. |
@ngehad I don't have any updates for now, but I still have this issue on my table |
@sandwwraith no need to mention the importance of this issue, as it affects our company teams decision when starting a new project or revamping old one, for which library to adopt |
Please take into account that performance is a delicate matter. Benchmarking is an analysis tool to supplement profiling, and without it, there is no interpretation of what library is "faster." We will avoid any generic comparisons, especially if they affect anyone's decision-making based on our claims. We can provide a commentary on the benchmarking methodology, see if we have any systematic performance issues (e.g. like #2743), and figure out whether there are some improvements for specific scenarios, use-cases or modes. Right now, we would like to ask you for a self-contained reproducer (the one that we can checkout/copy-paste & run) -- I've tested the data provided, but the data model and JSONs provided are mismatched -- there are seemingly incorrect property names, mismatched data types, missing non-optional fields etc. |
The string API is generally considered to be faster, see e.g. [1] and [2]. [1]: Kotlin/kotlinx.serialization#2186 [2]: Kotlin/kotlinx.serialization#2657 (comment) Signed-off-by: Sebastian Schuberth <[email protected]>
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).
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
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
The text was updated successfully, but these errors were encountered: