A library for binary serialization / deserialization without (unnecessary) allocation in C#
bool success = span.TryWrite(IntValue, out Span<byte> rest)
&& rest.TryWrite(LongValue, out rest)
&& rest.TryWrite(ShortValue, out _);bool success = span.TryRead(out int intValue, out Span<byte> rest)
&& rest.TryRead(out long longValue, out rest)
&& rest.TryRead(out short shortValue, out _);Requrements:
- .NET 6
- C# 10 preview
public record TestPersistable : IPersistable<TestPersistable> {
// abstract static intefrace override
public static bool TryRead(
ReadOnlySpan<byte> span,
out TestPersistable value,
out ReadOnlySpan<byte> rest)
=> InitializeOuts(out value, out rest)
&& span.TryRead(out int integerProp, out rest)
&& rest.TryRead(out string stringProp, out rest, Encoding.UTF8)
&& CreateInstance(integerProp, stringProp, out value);
public int IntegerProperty { get; init; }
public string StringProperty { get; init; }
// interface override
public int GetPersistedSizeInBytes()
=> sizeof(int)
+ sizeof(int) + Encoding.UTF8.GetByteCount(StringProperty);
// interface override
public bool TryWrite(Span<byte> span, out Span<byte> rest)
=> span.TryWrite(IntegerProperty, out rest)
&& rest.TryWrite(StringProperty, out rest, Encoding.UTF8);
// helper method for TryRead
private static bool InitializeOuts(
out TestPersistable persistable,
out ReadOnlySpan<byte> rest) {
persistable = default;
rest = default;
return true;
}
// helper method for TryRead
private static bool CreateInstance(
int integerProperty,
string stringProperty,
out TestPersistable persistable) {
persistable = new TestPersistable() {
IntegerProperty = integerProperty,
StringProperty = stringProperty,
};
return true;
}
}var persistable = new TestPersistable(){ IntegerProperty = 1, StringProperty = "foo" };
bool success = span.TryWrite(persistable, out Span<byte> rest);bool success = span.TryRead(out TestPersistable persistableValue, out Span<byte> rest);BenchmarkDotNet=v0.13.1, OS=Windows 10.0.22000
Intel Core i9-9900K CPU 3.60GHz (Coffee Lake), 1 CPU, 16 logical and 8 physical cores
.NET SDK=6.0.100-preview.7.21379.14
[Host] : .NET 6.0.0 (6.0.21.37719), X64 RyuJIT
DefaultJob : .NET 6.0.0 (6.0.21.37719), X64 RyuJIT
| Method | Categories | Mean | Error | StdDev | Ratio | RatioSD | Gen 0 | Allocated |
|---|---|---|---|---|---|---|---|---|
| SerializeByte | Serialize,AllocationFree | 0.4047 ns | 0.0031 ns | 0.0026 ns | 1.00 | 0.00 | - | - |
| SerializeInt32 | Serialize,AllocationFree | 0.4902 ns | 0.0039 ns | 0.0032 ns | 1.21 | 0.01 | - | - |
| SerializeInt64 | Serialize,AllocationFree | 0.4609 ns | 0.0064 ns | 0.0054 ns | 1.14 | 0.02 | - | - |
| SerializeSingle | Serialize,AllocationFree | 0.5561 ns | 0.0349 ns | 0.0358 ns | 1.38 | 0.10 | - | - |
| SerializeDouble | Serialize,AllocationFree | 0.5876 ns | 0.0029 ns | 0.0024 ns | 1.45 | 0.01 | - | - |
| SerializeString | Serialize,AllocationFree | 51.3988 ns | 0.1563 ns | 0.1462 ns | 127.08 | 0.92 | 0.0038 | 32 B |
| SerializeDateTime | Serialize,AllocationFree | 82.5058 ns | 0.1614 ns | 0.1510 ns | 203.85 | 1.46 | - | - |
| SerializeDateTimeOffset | Serialize,AllocationFree | 9.3971 ns | 0.0363 ns | 0.0340 ns | 23.23 | 0.20 | - | - |
| SerializePersistable | Serialize,AllocationFree | 60.4435 ns | 0.1597 ns | 0.1333 ns | 149.37 | 1.14 | 0.0038 | 32 B |
| SerializeByteJson | Serialize,Json | 115.4455 ns | 0.9579 ns | 0.8960 ns | 1.00 | 0.00 | 0.0219 | 184 B |
| SerializeInt32Json | Serialize,Json | 112.2672 ns | 0.2875 ns | 0.2549 ns | 0.97 | 0.01 | 0.0219 | 184 B |
| SerializeInt64Json | Serialize,Json | 111.4606 ns | 0.4073 ns | 0.3810 ns | 0.97 | 0.01 | 0.0219 | 184 B |
| SerializeSingleJson | Serialize,Json | 219.8054 ns | 1.1593 ns | 1.0844 ns | 1.90 | 0.02 | 0.0219 | 184 B |
| SerializeDoubleJson | Serialize,Json | 218.3641 ns | 1.6525 ns | 1.3799 ns | 1.89 | 0.02 | 0.0219 | 184 B |
| SerializeStringJson | Serialize,Json | 133.6537 ns | 0.9364 ns | 0.8301 ns | 1.16 | 0.01 | 0.0219 | 184 B |
| SerializeDateTimeJson | Serialize,Json | 257.4679 ns | 1.3805 ns | 1.2913 ns | 2.23 | 0.02 | 0.0296 | 248 B |
| SerializeDateTimeOffsetJson | Serialize,Json | 170.3939 ns | 1.3720 ns | 1.2833 ns | 1.48 | 0.02 | 0.0296 | 248 B |
| SerializePersistableJson | Serialize,Json | 215.6746 ns | 0.8641 ns | 0.7660 ns | 1.87 | 0.02 | 0.0324 | 272 B |
| DeserializeByte | Deserialize,AllocationFree | 0.2565 ns | 0.0050 ns | 0.0046 ns | 1.00 | 0.00 | - | - |
| DeserializeInt32 | Deserialize,AllocationFree | 0.4373 ns | 0.0056 ns | 0.0046 ns | 1.71 | 0.03 | - | - |
| DeserializeInt64 | Deserialize,AllocationFree | 0.4604 ns | 0.0044 ns | 0.0041 ns | 1.80 | 0.03 | - | - |
| DeserializeSingle | Deserialize,AllocationFree | 0.4365 ns | 0.0058 ns | 0.0051 ns | 1.71 | 0.04 | - | - |
| DeserializeDouble | Deserialize,AllocationFree | 0.4396 ns | 0.0043 ns | 0.0040 ns | 1.71 | 0.04 | - | - |
| DeserializeString | Deserialize,AllocationFree | 1.5146 ns | 0.0094 ns | 0.0088 ns | 5.91 | 0.11 | - | - |
| DeserializeDateTime | Deserialize,AllocationFree | 0.4697 ns | 0.0047 ns | 0.0044 ns | 1.83 | 0.04 | - | - |
| DeserializeDateTimeOffset | Deserialize,AllocationFree | 0.6007 ns | 0.0224 ns | 0.0209 ns | 2.34 | 0.10 | - | - |
| DeserializePersistable | Deserialize,AllocationFree | 26.3492 ns | 0.1198 ns | 0.1062 ns | 102.96 | 1.82 | 0.0076 | 64 B |
| DeserializeByteJson | Deserialize,Json | 110.9197 ns | 0.5239 ns | 0.4901 ns | 1.00 | 0.00 | - | - |
| DeserializeInt32Json | Deserialize,Json | 113.4686 ns | 0.8414 ns | 0.7459 ns | 1.02 | 0.01 | - | - |
| DeserializeInt64Json | Deserialize,Json | 113.2146 ns | 0.2604 ns | 0.2033 ns | 1.02 | 0.01 | - | - |
| DeserializeSingleJson | Deserialize,Json | 158.1268 ns | 0.6575 ns | 0.6150 ns | 1.43 | 0.01 | - | - |
| DeserializeDoubleJson | Deserialize,Json | 156.9926 ns | 0.2720 ns | 0.2124 ns | 1.42 | 0.01 | - | - |
| DeserializeStringJson | Deserialize,Json | 137.1684 ns | 0.3681 ns | 0.3263 ns | 1.24 | 0.01 | 0.0038 | 32 B |
| DeserializeDateTimeJson | Deserialize,Json | 140.7853 ns | 0.5063 ns | 0.4736 ns | 1.27 | 0.01 | - | - |
| DeserializeDateTimeOffsetJson | Deserialize,Json | 166.1167 ns | 0.5057 ns | 0.4223 ns | 1.50 | 0.01 | - | - |
| DeserializePersistableJson | Deserialize,Json | 308.3187 ns | 1.1390 ns | 1.0097 ns | 2.78 | 0.02 | 0.0076 | 64 B |