All Projects → skbkontur → GroBuf

skbkontur / GroBuf

Licence: MIT license
Fast binary serializer

Programming Languages

C#
18002 projects
Batchfile
5799 projects

Projects that are alternatives of or similar to GroBuf

Iguana
universal serialization engine
Stars: ✭ 481 (+758.93%)
Mutual labels:  serialization, binary
nason
🗜 Ultra tiny serializer / encoder with plugin-support. Useful to build binary files containing images, strings, numbers and more!
Stars: ✭ 30 (-46.43%)
Mutual labels:  serialization, binary
Pbf
A low-level, lightweight protocol buffers implementation in JavaScript.
Stars: ✭ 618 (+1003.57%)
Mutual labels:  serialization, binary
Fspickler
A fast multi-format message serializer for .NET
Stars: ✭ 299 (+433.93%)
Mutual labels:  serialization, binary
Binaryserializer
A declarative serialization framework for controlling formatting of data at the byte and bit level using field bindings, converters, and code.
Stars: ✭ 197 (+251.79%)
Mutual labels:  serialization, binary
Ceras
Universal binary serializer for a wide variety of scenarios https://discord.gg/FGaCX4c
Stars: ✭ 374 (+567.86%)
Mutual labels:  serialization, binary
Bincode
A binary encoder / decoder implementation in Rust.
Stars: ✭ 1,100 (+1864.29%)
Mutual labels:  serialization, binary
protodata
A textual language for binary data.
Stars: ✭ 35 (-37.5%)
Mutual labels:  serialization, binary
parco
🏇🏻 generalist, fast and tiny binary parser and compiler generator, powered by Go 1.18+ Generics
Stars: ✭ 57 (+1.79%)
Mutual labels:  serialization, binary
Borer
Efficient CBOR and JSON (de)serialization in Scala
Stars: ✭ 131 (+133.93%)
Mutual labels:  serialization, binary
GenericProtocol
⚡️ A fast TCP event based buffered server/client protocol for transferring data over the (inter)net in .NET 🌐
Stars: ✭ 38 (-32.14%)
Mutual labels:  serialization, binary
surge
Simple, specialised, and efficient binary marshaling
Stars: ✭ 36 (-35.71%)
Mutual labels:  serialization, binary
binary
package binary is a lightweight and high-performance serialization library to encode/decode between go data and []byte.
Stars: ✭ 20 (-64.29%)
Mutual labels:  serialization, binary
Fastbinaryencoding
Fast Binary Encoding is ultra fast and universal serialization solution for C++, C#, Go, Java, JavaScript, Kotlin, Python, Ruby, Swift
Stars: ✭ 421 (+651.79%)
Mutual labels:  serialization, binary
sia
Sia - Binary serialisation and deserialisation
Stars: ✭ 52 (-7.14%)
Mutual labels:  serialization, binary
Beeschema
Binary Schema Library for C#
Stars: ✭ 46 (-17.86%)
Mutual labels:  serialization, binary
persistity
A persistence framework for game developers
Stars: ✭ 34 (-39.29%)
Mutual labels:  serialization, binary
hs-packer
Fast serialization in haskell
Stars: ✭ 13 (-76.79%)
Mutual labels:  serialization, binary
Binary
Generic and fast binary serializer for Go
Stars: ✭ 86 (+53.57%)
Mutual labels:  serialization, binary
Chronicle Wire
A Java Serialisation Library that supports multiple formats
Stars: ✭ 204 (+264.29%)
Mutual labels:  serialization, binary

GroBuf

NuGet Status Build Status Build status

GroBuf is a fast binary serializer for .NET.

Example

Imagine a simple class hierarchy:

public class Car
{
    public Guid? Id { get; set; }
    public string Manufacturer { get; set; }
    public CarKind Kind { get; set; }
    public Wheel[] Wheels { get; set; }
}
public class Wheel
{
    public double Radius { get; set; }
    public double Width { get; set; }
    public double Weight { get; set; }
}
public enum CarKind : byte
{
    Sedan,
    Hatchback,
    Limousine,
    Van
}

Creating a serializer

In order to obtain maximum speed it is strongly recommended to use a single instance of the serializer as it dynamicly generates code for serialization/deserialization methods. Instances of the serializer are considered to be thread-safe.

var serializer = new Serializer(new PropertiesExtractor(), options : GroBufOptions.WriteEmptyObjects);

Here we create serializer in order to read/write all public properties. By default GroBuf skips objects which are empty (an object is considered empty if it is an array with zero length or if all its members are empty). The GroBufOptions.WriteEmptyObjects options says GroBuf to write all data as is.

Serializing/Deserializing

GroBuf serializes objects to binary format and returns byte[], deserializes from byte[]:

var car = new Car
              {
                  Id = Guid.NewGuid(),
                  Manufacturer = "zzz",
                  Kind = CarKind.Limousine,
                  Wheels = new[] { new Wheel {Radius = 19.1, Width = 5.2, Weight = 16.9} }
              };
byte[] data = serializer.Serialize(car);
var zcar = serializer.Deserialize<Car>(data);

Selecting members to serialize

It is possible to create a serializer with custom data members selection. These are predefined extractors:

  • PropertiesExtractor - selects all public properties
  • FieldsExtractor - selects all public fields
  • AllPropertiesExtractor - selects both public and private properties
  • AllFieldsExtractor - selects both public and private fields
  • DataMembersByAttributeExtractor - selects all members marked with DataMember attribute

Notes on types

Supports:

  • custom classes or structs
  • primitive types
  • single dimension arrays
  • List<>, HashSet<>, Hashtable, Dictionary<,>
  • Lazy<> (it will not be deserialized untill Value is actually demanded)

Serialized types names are not used and therefore the types can be safely renamed without any loss of data.

All primitive types are convertible into ecch other. For example, if a data contract member had type int and has been changed to long than no old data will be lost.

Notes on members

The members's names are important for GroBuf because it stores hash codes of all serialized members and uses them during deserialization. But it is possible to tell GroBuf what hash code is to be used for a particular member using GroboMember attribute. If a member's name changes (and there is no GroboMember attribute at it) or a member has been deleted, old data still may be deserialized but the data of that particular member will be skipped and lost. If a member has been added than after deserializing old data, the value of this member will be set to its default value.

Notes on enums

Enums are stored not as ints but as hash codes for their string representation. Thus, one can safely change the value of enum, but change fo a name will result in loss of data (soon it will be possibile to specify the hash code of a enum member manually).

Performance

GroBuf is faster than a well-known serializer ProtoBuf:

  • about 2-2.5 times on average on serialization
  • about 4-5 times on average on deserialization

Here you can see an example of benchmarking in a realistic scenario:

BenchmarkDotNet-Dev=v0.9.6.0+
OS=Microsoft Windows NT 6.1.7601 Service Pack 1
Processor=Intel(R) Core(TM) i7-2600K CPU 3.40GHz, ProcessorCount=8
Frequency=3312861 ticks, Resolution=301.8539 ns, Timer=TSC
HostCLR=MS.NET 4.0.30319.42000, Arch=64-bit RELEASE [RyuJIT]
JitModules=clrjit-v4.6.1076.0

Type=ProtoBufvsGroBufRunner  Mode=Throughput  

              Method | Platform |       Jit | Runtime |      Median |    StdDev |
-------------------- |--------- |---------- |-------- |------------ |---------- |
     GroBufSerialize |     Host |      Host |    Mono |  79.0364 us | 0.6419 us |
   GroBufDeserialize |     Host |      Host |    Mono |  17.6128 us | 0.1588 us |
   ProtoBufSerialize |     Host |      Host |    Mono | 184.1507 us | 1.7764 us |
 ProtoBufDeserialize |     Host |      Host |    Mono |  72.3540 us | 2.2473 us |
     GroBufSerialize |      X64 | LegacyJit |    Host |  52.2340 us | 2.1481 us |
   GroBufDeserialize |      X64 | LegacyJit |    Host |   8.9056 us | 0.5137 us |
   ProtoBufSerialize |      X64 | LegacyJit |    Host | 136.6818 us | 5.9596 us |
 ProtoBufDeserialize |      X64 | LegacyJit |    Host |  38.0563 us | 1.5057 us |
     GroBufSerialize |      X64 |    RyuJit |    Host |  49.3948 us | 1.5682 us |
   GroBufDeserialize |      X64 |    RyuJit |    Host |   9.4304 us | 0.3034 us |
   ProtoBufSerialize |      X64 |    RyuJit |    Host | 136.9129 us | 5.1180 us |
 ProtoBufDeserialize |      X64 |    RyuJit |    Host |  37.7057 us | 0.5454 us |
     GroBufSerialize |      X86 | LegacyJit |    Host |  60.7610 us | 0.5057 us |
   GroBufDeserialize |      X86 | LegacyJit |    Host |  12.2245 us | 0.1467 us |
   ProtoBufSerialize |      X86 | LegacyJit |    Host | 156.2833 us | 3.5322 us |
 ProtoBufDeserialize |      X86 | LegacyJit |    Host |  41.5833 us | 0.5682 us |

The disadvantages are:

  • because of simpler format the size of data produced by GroBuf is 1.5-2 times larger than ProtoBuf's. But it is planned to be optimized in the future
  • lack of ProtoBuf's extensions

Release Notes

See CHANGELOG.

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].