views:

87

answers:

1

I've just updated from r249 to r282. Other than replacing the dll I've made no changes. Unfortunately, now deserializing the objects created before the update takes significantly longer. What used to take two seconds now takes five minutes.

Were there syntax changes between versions? Is there anything it no longer supports?

My classes are all using ProtoContract, ProtoMember, and ProtoInclude. I am running VS2010. As far as I was concerned there were no problems with my protocol buffer code. I'm only trying to upgrade because I figured it's good to have the most recent version.

Edit - 2010.09.09 One of the properties of my object is an array of ushorts. I've just noticed that this property did not serialize/deserialize properly with r282. The resulting values of the array are all zeros. The array had values before being serialized (r282) but not after deserialization (r282).

+2  A: 

It turns out that despite my efforts, yes there was a breaking change in data format in one of the earlier builds. This only impacts ushort data, which was omitted from the handling at one point. This is regrettable, but the good news is that no data is lost - it is simply a bit inconvenient to access (it is essentially written via a string at the moment).

Here's my suggested workaround; for a member like:

[ProtoBuf.ProtoMember(1)]
public ushort[] Data {get;set;}

Replace that with:

[ProtoBuf.ProtoMember(1)]
private string[] LegacyData {get;set;}

private bool LegacyDataSpecified { get { return false; } set { } }

/* where 42 is just an unused new field number */
[ProtoBuf.ProtoMember(42, Options = MemberSerializationOptions.Packed)]
public ushort[] Data { get; set; }

[ProtoBuf.ProtoAfterDeserialization]
private void SerializationCallback()
{
    if (LegacyData != null && LegacyData.Length > 0)
    {
        ushort[] parsed = Array.ConvertAll<string, ushort>(
            LegacyData, ushort.Parse);
        if (Data != null && Data.Length > 0)
        {
            int oldLen = parsed.Length;
            Array.Resize(ref parsed, parsed.Length + Data.Length);
            Array.Copy(Data, 0, parsed, oldLen, Data.Length);
        }
        Data = parsed;
    }
    LegacyData = null;
}

This imports old-style data into LegacyData and merges it during (after) serialization, or writes new-style data from Data. Faster, smaller, and supports both old and new data.

Marc Gravell
Please read additions to the original post.
Dan Vogel
@Dan - OK, that helps. I was about to turn in for today, but will investigate this tomorrow. Very odd!
Marc Gravell
Any update on this?
Dan Vogel
@Dan - I'm actually looking at it now; sorry, lots of competing time pressures
Marc Gravell
@Dan - see update; tested with v1 branch and the released dll. Can you provide more context so I can reproduce a failing case?
Marc Gravell
I've sent you an email with further detail.
Dan Vogel
@Dan - identified and updated
Marc Gravell