La sérialisation binaire ultra efficace avec Protobuf-net
Publié le 17/02/2025
Par  Christophe MOMMER

La sérialisation de données est un enjeu majeur pour de nombreuses applications, qu’il s’agisse de communiquer entre services, de stocker des données ou d’optimiser les performances. Aujourd’hui, nous allons découvrir protobuf-net, une librairie .NET qui permet d’utiliser Protocol Buffers (ou protobuf), un format de sérialisation binaire très performant développé par Google.

Même si le format JSON règne aujourd'hui en maître sur les échanges entre les services, le format binaire de protobuf peut s'avérer fort utile et fort pratique pour la communication entre les différents services de votre infrastructure, notamment pour réduire l'empreinte des transferts réseaux.

La librairie que je vais vous présenter est complète & performante, il s'agira donc d'une simple introduction. Pour le reste, je vous renvoie vers le dépôt officiel de cette dernière.

Première étape assez évident : installer le package (soit par le gestionnaire de package nuget de votre IDE, soit par la ligne de commande avec  dotnet add package protobuf-net

Prenons un exemple très simple pour que tout le monde puisse comprendre, la fameuse classe Person. La librairie va générer automatiquement les informations de contrat proto avec des attributs (ProtoContract au-dessus de la classe, ProtoMember avec la position de l'élément dans le flux du contract au-dessus des propriétés), que ce soit pour la sérialisation ou la déserialisation :

using ProtoBuf;

[ProtoContract]
public class Person
{
    [ProtoMember(1)]
    public int Id { get; set; }

    [ProtoMember(2)]
    public string Name { get; set; }

    [ProtoMember(3)]
    public DateTime BirthDate { get; set; }
}

Une fois cela fait, il suffira d'utiliser la classe Serializer du package pour faire les opérations de sérialisation ou de déserialisation :

Person person = new { Id = 1, Name = "Christophe Mommer", BirthDate = new(1988, 12, 18) };

using var stream = new MemoryStream();
Serializer.Serialize(stream, person);

var bytes = stream.ToArray();

La librairie est très simple a utiliser, mais assez extensible et personnalisable pour des cas d'usages avancés.

Pour comparer la taille du flux protobuf par rapport à un équivalent JSON et XML, on arrive sur cet ordre de grandeur

  • XML = 252 bytes
  • JSON = 69 bytes
  • Protobuf = 26 bytes

Pour ce qui est de la performance :

En bref, protobuf-net offre une belle alternative pour pouvoir implémenter la communication dans les cas où ce n'est pas géré nativement avec gRPC