user1784317
user1784317

Reputation: 41

Many subclasses for one base class - protobuf performance

Right now I have an application where my iPhone app sends a request that is handled in .NET/C#, serialized to XML, and parsed on the app in objective-c. The current response class structure has one base class (BaseResponse) and many (over 25) subclasses for each type of request that corresponds to different things that need to be returned. Right now I'm looking to see if protobuf would be faster and easier than XML. From what I understand, a .proto file for this class structure is:

Message BaseResponse {
Required Int field1 = 1;
Optional SubResponse1 sub1= 2;
Optional SubResponse2 sub2 = 3;
Etc....
}

Message SubResponse1 {
....
}

Message SubResponse2 {
....
}
Etc for each sub response.

My question is: if I have over 25 of these optional elements (of which only 1 will be non null), does that completely wipe away the size and performance benefit of using protobuf? Does protobuf make sense for this application?

Upvotes: 1

Views: 1367

Answers (1)

Marc Gravell
Marc Gravell

Reputation: 1062865

No, it does not impact the performance benefit - you'll just need to check which one is non-null in the objective-C code. Since protobuf only serializes the non-null values it will still be very efficient over the wire. The protobuf specification itself doesn't actually include inheritance, so you are right to say that you need to spoof it via encapsulation - but since you mention C#, note that what you have described (including how the data appears on the wire, i.e. it will be 100% comptible) can be done directly via inheritance if you use protobuf-net as the C# implementation - which should be possible with your existing model. For example:

[ProtoContract]
[ProtoInclude(2, typeof(SubResponse1))]
[ProtoInclude(3, typeof(SubResponse2))]
public class BaseResponse
{
    // note Name and IsRequired here are optional - only
    // included to match your example
    [ProtoMember(1, IsRequired = true, Name="field1")]
    public int Field1 { get; set; }
    /*...*/
}
[ProtoContract]
public class SubResponse1 : BaseResponse
{/*...*/}
[ProtoContract]
public class SubResponse2 : BaseResponse
{/*...*/}

You can get the .proto via:

var proto = Serializer.GetProto<BaseResponse>();

Which gives:

message BaseResponse {
   required int32 field1 = 1 [default = 0];
   // the following represent sub-types; at most 1 should have a value
   optional SubResponse1 SubResponse1 = 2;
   optional SubResponse2 SubResponse2 = 3;
}
message SubResponse1 {
}
message SubResponse2 {
}

Upvotes: 1

Related Questions