dseinternational / open-dotnet

Libraries and tools supporting DSE Open systems and technologies.
MIT License
0 stars 0 forks source link

Investigate MessagePack for serialization format #150

Closed frankbuckley closed 2 months ago

frankbuckley commented 2 months ago

Explore if size/speed gains.

Get BinaryWordSnapshotSet working with MessagePack - then benchmark a set of 500 snapshots serialize/deserialize and measure payload sizes

rabuckley commented 2 months ago
// Copyright (c) Down Syndrome Education International and Contributors. All Rights Reserved.
// Down Syndrome Education International and Contributors licence this file to you under the MIT license.

using System.Text.Json;
using BenchmarkDotNet.Attributes;
using DSE.Open.Collections.Generic;
using DSE.Open.Language;
using DSE.Open.Observations;
using DSE.Open.Values;
using MessagePack;

namespace DSE.Open.Benchmarks.MessagePack;

#pragma warning disable CA1822

[MemoryDiagnoser(false)]
public class MessagePackBenchmarks
{
    private static readonly Uri s_uri = new("https://schema-test.dseapi.app/testing/measure");

    private static readonly BinaryMeasure s_binaryMeasure =
        new(MeasureId.GetRandomId(), s_uri, "Test measure", "[subject] does something");

    private static readonly ReadOnlyValueCollection<BinaryWordSnapshot> s_collection =
    [
        BinaryWordSnapshot.ForUtcNow(BinaryWordObservation.Create(s_binaryMeasure, WordId.GetRandomId(), true))
    ];

    private static readonly BinaryWordSnapshotSet s_set = BinaryWordSnapshotSet.Create(Identifier.New(), s_collection);

    [Benchmark]
    public BinaryWordSnapshotSet MessagePack()
    {
        var bytes = MessagePackSerializer.Serialize(s_set);
        return MessagePackSerializer.Deserialize<BinaryWordSnapshotSet>(bytes);
    }

    [Benchmark(Baseline = true)]
    public BinaryWordSnapshotSet Json()
    {
        var bytes = JsonSerializer.SerializeToUtf8Bytes(s_set);
        return JsonSerializer.Deserialize<BinaryWordSnapshotSet>(bytes)!;
    }
}
BenchmarkDotNet v0.14.0, macOS Sonoma 14.6.1 (23G93) [Darwin 23.6.0]
Apple M1 Pro, 1 CPU, 10 logical and 10 physical cores
.NET SDK 8.0.303
  [Host]     : .NET 8.0.8 (8.0.824.36612), Arm64 RyuJIT AdvSIMD
  DefaultJob : .NET 8.0.8 (8.0.824.36612), Arm64 RyuJIT AdvSIMD
Method Mean Error StdDev Ratio Allocated Alloc Ratio
MessagePack 532.9 ns 3.32 ns 2.94 ns 0.31 1016 B 0.45
Json 1,744.7 ns 9.05 ns 8.47 ns 1.00 2272 B 1.00

cc. @frankbuckley

rabuckley commented 2 months ago

Message Pack Bytes

165

95 C4 28 73 6E 70 5F 68 74 71 64 48 45 31 6A 6E 4D 70 68 67 58 4B 4B 78 45 68 4D 37 4B 67 59 6D 4D 59 57 43 74 45 42 6D 49 4B 34 CF 00 00 01 91 50 52 0D 50 CF 00 00 01 91 50 52 0D 50 C4 30 31 4E 79 71 58 50 52 4F 6E 68 4B 73 52 78 76 77 4B 39 6E 38 65 6B 70 4D 53 66 65 38 36 32 39 6A 49 41 4D 43 38 74 52 4C 36 56 46 6E 74 7A 30 71 91 94 92 D7 FF 4F C7 F3 40 66 BC 7F 80 00 C0 C0 95 CF 00 02 B8 E4 57 19 28 E0 CF 00 00 00 37 D9 A5 30 22 CF 00 00 01 91 50 52 0D 4B C3 CF 00 00 00 7A 00 81 12 A5

Json Bytes

262

7B 22 69 64 22 3A 22 73 6E 70 5F 68 74 71 64 48 45 31 6A 6E 4D 70 68 67 58 4B 4B 78 45 68 4D 37 4B 67 59 6D 4D 59 57 43 74 45 42 6D 49 4B 34 22 2C 22 63 72 74 22 3A 31 37 32 33 36 32 39 34 34 30 33 33 36 2C 22 75 70 64 22 3A 31 37 32 33 36 32 39 34 34 30 33 33 36 2C 22 74 72 6B 22 3A 22 31 4E 79 71 58 50 52 4F 6E 68 4B 73 52 78 76 77 4B 39 6E 38 65 6B 70 4D 53 66 65 38 36 32 39 6A 49 41 4D 43 38 74 52 4C 36 56 46 6E 74 7A 30 71 22 2C 22 6F 62 73 22 3A 5B 7B 22 6F 22 3A 7B 22 69 22 3A 37 36 36 32 34 30 38 30 36 37 34 32 32 34 30 2C 22 74 22 3A 31 37 32 33 36 32 39 34 34 30 33 33 31 2C 22 6D 22 3A 32 33 39 38 37 34 36 38 32 39 31 34 2C 22 64 22 3A 35 32 33 39 39 34 34 36 39 30 32 39 2C 22 76 22 3A 74 72 75 65 7D 2C 22 74 22 3A 31 37 32 33 36 32 39 34 34 30 33 33 34 7D 5D 7D
rabuckley commented 2 months ago

Using Bogus.Faker to generate lorem to avoid duplicate strings (fighting unrealistic compression), we get:

Creating 500 BinaryWordSnapshots
Message Pack Bytes: 26614
Json Bytes: 54099
frankbuckley commented 2 months ago

Leave for now