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

BinarySerializer is sub-optimal for ProtoBuf #422

Open
bcmedeiros opened this issue Dec 14, 2024 · 0 comments
Open

BinarySerializer is sub-optimal for ProtoBuf #422

bcmedeiros opened this issue Dec 14, 2024 · 0 comments

Comments

@bcmedeiros
Copy link

bcmedeiros commented Dec 14, 2024

I have a serializable class whose 2 first fields are a Uuid in need of a binary serializer, so I set up @file:UseContextualSerialization(Uuid::class) for them and tried to use the BinarySerializer provided by this library.

After looking at https://protobuf-decoder.netlify.app/ to see what the payload looked like, this is what I got:
image
(image for 08 d9 84 9d 86 d1 f6 8b aa eb 01 08 bd cf ff be 82 c8 a8 ef b5 01 10 84 90 89 b5 c7 d7 be 91 96 01 10 89 c6 c4 ca ca f4 f3 b6 a9 01)

I was not quite happy with the results, ~22 bytes per uuid is a lot of overhead, so I decided to test another serializer using a byte array and the results improved quite a lot:
image
(image for 0a 10 bb e3 92 bd 34 e5 47 9d 83 b1 9e bb b2 f5 ee 88 12 10 0a 51 15 dc 61 36 43 0e a5 ee 9b 7d 60 4e e3 4f)

With the new serializer, the overhead is 2 bytes per uuid instead of 6. It's also much easier to reason about and inspect in debug tools when needed to (the visual representation in the screenshot above is almost the dash representation of the uuid).

I propose the class below is added to this library:

public object UuidByteArraySerializer : KSerializer<Uuid> {
    private val serializer = ByteArraySerializer()
    override val descriptor: SerialDescriptor = SerialDescriptor("kotlin.uuid.Uuid.binary", serializer.descriptor)

    override fun serialize(encoder: Encoder, value: Uuid) {
        val byteArray = value.toByteArray()
        encoder.encodeSerializableValue(serializer, byteArray)
    }

    override fun deserialize(decoder: Decoder): Uuid {
        val byteArray = decoder.decodeSerializableValue(serializer)
        return Uuid.fromByteArray(byteArray)
    }
}

I can raise a PR if you think it's worth.

We may also deprecate BinarySerializer as well, unless its performance is much better in Cbor in which case a new name might help.

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

1 participant