Gilles
Gilles

Reputation: 5407

protobuf-net Serialization performance question

I have started testing protobuf-net for serialization. I had seen benchmarks (http://www.servicestack.net/benchmarks/NorthwindDatabaseRowsSerialization.100000-times.2010-08-17.html) which suggested faster serialization and smaller files.

I am really seeing a huge difference in the size of the produced files. However, the speed I am seeing is within 5% of WCF's DataContractSerializer.

That left me wondering if I am doing something wrong?

Here is my tests's code:

private static void ProtoBufSerializer(IQueryable<DataRow> details)
    {
        List<DataRow> list = details.ToList();

        using (var file = File.Create("protobuf2.bin"))
        {                
            Serializer.Serialize<List<DataRow>>(file, list);
        }
    }

    private static void DataContractSerializer(IQueryable<DataRow> details)
    {
        DataContractSerializer serializer = new DataContractSerializer(typeof(List<DataRow>));
        List<DataRow> list = details.ToList();

        using (FileStream fileStream = new FileStream("testSerializationDataContract.xml", FileMode.Create))
        {
            serializer.WriteObject(fileStream, list);
        }            
    }

[ProtoContract]
public class DataRow
{
    [ProtoMember(1)]
    public DRFDataRow DrfDataRow;

    [ProtoMember(2)]
    public Guid guid;
}

[ProtoContract]
public class DRFDataRow : FixedWidthRow
{
    [ProtoMember(1)]
    public int CompanyNumber { get; set; }

    // several fields abreviated for brevety
}

[ProtoContract, ProtoInclude(100, "DRFDataRow")]
public abstract class FixedWidthRow : IProviderRow
{
    // several fields abreviated for brevety

There are about 73k items in my List. Each item isn't too big, altough there are a lot of fields in DRFDataRow (about 50).

P.S.: I am not complaining, I am very happy with the results since the serialized results size is so much smaller, I am just wondering if I can also reproduce the speed gains I have seen on benchmarks.

Upvotes: 1

Views: 722

Answers (1)

Marc Gravell
Marc Gravell

Reputation: 1062865

In that example it isn't entirely clear where the timing starts and ends - for example, if you are including the time to fetch data from the IQueryable[<T>] then that will most likely be a bottle-neck. The contracts look fine; there are some small optimisations possible if you like, but nothing major (although using group-based sub-objects should help a bit by avoiding some buffering; add DataFormat=DataFormat.Group to the sub-object [ProtoMember(... {here})] and [ProtoInclude(... {here})]).

If the issue isn't the IQueryable[<T>], then it may well be worth trying v2 (currently available as an alpha, or as source) which completely overhauls the internals.

For a more detailed answer, I'd need a fully reproducible example to investigate.

Upvotes: 1

Related Questions