Skip to content

Optimize JsonElement #2791

Open
Open
@swankjesse

Description

@swankjesse

I’m using kotlinx.serialization on Kotlin/JS. I wrote some code that did something like this:

    val value = 1L
    val jsonElement = Json.encodeToJsonElement(value)
    val dynamic = Json.encodeToDynamic(jsonElement)

(In my actual code, each of these 3 lines happen in different parts of the application. And in my actual code, the value is a more sophisticated data class.)

When I ran this code, it was super slow! In particular I found that a severe bottleneck for my entire program was encoding 1L as a string, and then converting it back to a number.

In particular, this code in JsonElementSerializer was a hot spot:

https://github.com/Kotlin/kotlinx.serialization/blob/master/formats/json/commonMain/src/kotlinx/serialization/json/JsonElementSerializers.kt#L120-L122

        // use .content instead of .longOrNull as latter can process exponential notation,
        // and it should be delegated to double when encoding.
        value.content.toLongOrNull()?.let { return encoder.encodeLong(it) }

This is partly because Long is inefficient on Kotlin/JS, and partly because String.toLongOrNull() does a lot of work.

I was able to get dramatically better performance by skipping the JsonElement intermediate model:

    val value = 1L
    val dynamic = Json.encodeToDynamic(value)

Here’s the actual PR if you’re curious.

I would like for JsonElement to be a low-cost abstraction. In particular I believe the before & after samples above should have similar performance.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions