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

Improve serialization performance of value classes that require only unboxing. #715

Open
k163377 opened this issue Oct 9, 2023 · 5 comments

Comments

@k163377
Copy link
Contributor

k163377 commented Oct 9, 2023

The name of the annotation to be introduced are currently under discussion.
JsonKUnbox is the current first choice.

Please refer to the exchange in the comments for restrictions on naming.
If you have a better name, please suggest it.


Use case

In jackson-module-kotlin, when serializing a value class, even if it is unboxed, the procedure is to box it once and unbox it again if necessary.
This is necessary to enable features such as JsonValue and custom serializers.

Since this is done at each serialization call, the performance is greatly reduced compared to using a normal class (data class + JsonValue).
Verification with kogera confirms this(Although kogera is strictly a different project, there are no major differences in processing).
image

On the other hand, the main use case for the value class would be to simply output the unboxed value.
In that case, these overheads are completely useless.

Describe the solution you'd like

I am thinking of providing some way to skip those processes if only unboxing is required.

In my personal experimental project jackson-module-kogera, I implemented a way to specify it by means of an annotation named JsonUnbox.
https://github.com/ProjectMapK/jackson-module-kogera/blob/develop/src/main/kotlin/io/github/projectmapk/jackson/module/kogera/annotation/JsonUnbox.kt

This annotation is used by attaching it to a value class or a property getter that returns a value class.
https://github.com/ProjectMapK/jackson-module-kogera/blob/e9111c22124f789b66ac0201ce8d8a1156b24110/src/test/kotlin/io/github/projectmapk/jackson/module/kogera/_integration/ser/value_class/json_unbox/ForClass.kt#L9-L11
https://github.com/ProjectMapK/jackson-module-kogera/blob/e9111c22124f789b66ac0201ce8d8a1156b24110/src/test/kotlin/io/github/projectmapk/jackson/module/kogera/_integration/ser/value_class/json_unbox/ForProperty.kt#L18-L39

This is included in 2.15.2-beta5.

Benchmarking confirms that it can provide better performance than data class + JsonValue.
image

I also considered adding an option to limit the basic behavior regarding value class to unboxing, but have not worked on it yet as it would be more difficult to implement.

Additional context

I am considering implementing the JsonUnbox annotation on the jackson 2.17 target.

Please post any other requests for the name or behavior of this annotation, or for value class serialization performance improvements, to this issue.

@cowtowncoder
Copy link
Member

If this is Kotlin-specific annotation, and included in Kotlin module, perhaps name of KotlinUnbox would make more sense?

If (and only if) it could apply to other cases, annotation would go in jackson-annotations and then would follow JsonXxx naming pattern (even if these are not really JSON-specific either, most are applicable to other formats).

@k163377
Copy link
Contributor Author

k163377 commented Oct 10, 2023

Wouldn't it be enough to just place it in the com.fasterxml.jackson.module.kotlin package?
I like the name JsonUnbox because it is easy to see that it is an annotation related to Jackson.
I feel that the name KotlinUnbox is not so good because it misleads people into thinking that it is provided by Kotlin.

If (and only if) it could apply to other cases, annotation would go in jackson-annotations

I don't see any other use case for kotlin-module at the moment, so placing it in jackson-annotations seems inappropriate (it may be worth revisiting when Project Valhalla becomes available).

@cowtowncoder
Copy link
Member

Yes, inside Kotlin is fine.

But I don't like the use @Json prefix if it's part of Kotlin module. That should be reserved for general-use annotations; mostly in jackson-annotations but some injackson-databind.
I can see potential confusion for @Kotlin if such annotations are offered by Kotlin platform components?

Basically I feel that there needs to be something to indicate this is not generally usable with Jackson functionality outside of Kotlin module. This is what other modules do when they contain annotations @JacksonXmlText. I gue

So maybe @KUnbox or @JacksonKotlinUnbox or @JsonKotlinUnbox would be better.

@k163377
Copy link
Contributor Author

k163377 commented Oct 16, 2023

Personally, I think JsonKUnbox is the simplest and best.

@cowtowncoder
Copy link
Member

@k163377 I'm fine with that, so let's go with it.

k163377 added a commit to ProjectMapK/jackson-module-kogera that referenced this issue Oct 27, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants