zhejiushizhuce / protobuf-net

Automatically exported from code.google.com/p/protobuf-net
0 stars 0 forks source link

Issues with graph serilisation with circular references #163

Open GoogleCodeExporter opened 9 years ago

GoogleCodeExporter commented 9 years ago
I've turned on the ProtoMember options but the message size is the same, the 
execution time is also quite high compared to the Normal DataContractSerilizer. 
I have an object with an array of objects and they have cyclic references. 

Protobuf-net seems to correctly serialise but it seems to create clones of the 
referenced arrays even with DataMember / ProtoMember options.

Does Protomember override DataMember ? Must I remove DataMember ? In production 
really I need ability for possibly both with Proto override ?

Heres results with just ProtoMemeber Attributes...

Time(ms), Bytes Sent, Bytes Recieved
Protobuf-net No References, 115, 416, 1079532
Protobuf-net References,      113, 416, 1079532
Protobuf-net Dynamic Ref,    114, 416, 1079532

I have a test harness I can share, is there a more suitable place to have this 
discussion ?

thanks

David

Please feel free to contact me on:- dmarsh26@hotmail.com

Original issue reported on code.google.com by dmars...@gmail.com on 17 Mar 2011 at 4:41

Attachments:

GoogleCodeExporter commented 9 years ago
Full example project...

Original comment by dmars...@gmail.com on 17 Mar 2011 at 5:02

Attachments:

GoogleCodeExporter commented 9 years ago
I will need to verify that it is picking this up for lists, etc

Original comment by marc.gravell on 17 Mar 2011 at 6:47

GoogleCodeExporter commented 9 years ago
It appears the standard DataContractSerializer is being used as a fallback.

I tried adding this to fix it :-

            // TODO - Remove in final release version of protobuf-net..
            Serializer.PrepareSerializer<Order>();
            Serializer.PrepareSerializer<OrderLine>();
            Serializer.PrepareSerializer<AdvancedContainer>();
            Serializer.PrepareSerializer<AdvancedContainer[]>();
            Serializer.PrepareSerializer<byte[]>();

However I then get an 'Invalid type owner for DynamicMethod.' error for 
AdvancedContainer[] type.

I finally removed my arrays and changed my interface and added this :-

            Serializer.PrepareSerializer<List<AdvancedContainer>>();

However this did not seem to work either, its as if collection types must be 
wrapped to be serialized ?

Original comment by dmars...@gmail.com on 20 Mar 2011 at 7:09

GoogleCodeExporter commented 9 years ago
I haven't had chance to look at this yet; it'll depend on whether it is v1 or 
v2; v1 doesn't include object reference support; v2 is still in-progress; I 
would need to check to see if the WCF hooks are in place yet.

Original comment by marc.gravell on 20 Mar 2011 at 8:08

GoogleCodeExporter commented 9 years ago
Hi Marc, I'm building from source from the head so I guess its v2, and pretty 
recent code ?

The actual core serializer appears ok I think, the issue seems to be that the 
AdvancedContainer[] type is not recognized as a valid serilizable type in the 
integration layer so the protobuf serilizer is not used. See 
ProtoOperationBehaviour line 16.

        public override XmlObjectSerializer CreateSerializer(Type type, System.Xml.XmlDictionaryString name, System.Xml.XmlDictionaryString ns, IList<Type> knownTypes)
        {
            if (Serializer.NonGeneric.CanSerialize(type)) <-- this fails with my type
            {

To try to fix thus I used the PrepareSerializer code however this does not work 
as mentioned as it appears an array can't be the owner of a DynamicMethod.

It also appears that unwraped primitive types are going through the 
DataContactSerializer.

Many thanks

David

Original comment by dmars...@gmail.com on 21 Mar 2011 at 2:56

GoogleCodeExporter commented 9 years ago
Now have an example with just wrapped Lists and no arrays and it works, 
performance is not as good as DataContractSerializer with references on but 
acceptable.

It would be great to get unwrapped collections and general array support added 
though.

Also as mentioned it seems primitive/native types fall back to 
DataContractSerialiser also if unwrapped.

By unwrapped I mean they are passed on the WCF service interface and not 
enclosed in some other DTO style class.

Original comment by dmars...@gmail.com on 23 Mar 2011 at 2:03

GoogleCodeExporter commented 9 years ago
> Also as mentioned it seems primitive/native types fall back to 
DataContractSerialiser also if unwrapped.

yes, this is by design; protubuf *mainly* focus on entire object. Is there a 
specific scenario that is troubling you here?

I will look at the points above

Original comment by marc.gravell on 24 Mar 2011 at 8:37

GoogleCodeExporter commented 9 years ago
Ok, wasn't sure if this was by design, I was expecting the protobuf
serialiser to be the default serialsier for everything one activated.

Basically I was looking into the performance benefits of protobuf
serialisation in .NET, I've created a test harness to that end.

The idea was to see it it could be used as a general purpose serialiser on
most WCF interfaces that only require .NET binary interop.

So far the answer is not clear as on small messages it performs similarly to
DataContractSerializer, it benefits slightly on bigger payloads but then it
does not handle graphs as well as DataContactSerializer with reference
support on.

What are the reccomended usage patterns for protobuf-net ?

Original comment by dmars...@gmail.com on 25 Mar 2011 at 9:34