Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Deserializing dynamic types? #255

Open
rogeralsing opened this issue Jan 23, 2017 · 5 comments
Open

Deserializing dynamic types? #255

rogeralsing opened this issue Jan 23, 2017 · 5 comments

Comments

@rogeralsing
Copy link
Contributor

rogeralsing commented Jan 23, 2017

In Proto.Actor, we have this bit of code for deserializing any proto message from our envelope type like so:

func deserialize(message *MessageEnvelope) proto.Message {
	t1 := proto.MessageType(message.TypeName) //get the go type from the proto type name
        t := t1.Elem() 
	intPtr := reflect.New(t) //create an instance of the type
	instance := intPtr.Interface().(proto.Message)  //get the message data from the envelope
	proto.Unmarshal(message.MessageData, instance) //fill the instance with the data 

	return instance
}

This works, but it feels somewhat hacky to have to resort to reflection here.

In C# using Protobuf, we only need to do:

public static object Deserialize(string typeName, ByteString bytes)
{
    var parser = TypeLookup[typeName];
    var o = parser.ParseFrom(bytes);
    return o;
}

I can however not see any such infrastructure in Go.
Is there a better way of solving the above or is that as good as it gets?

I do know about protobuf "Any" types, but AFAIK, not all languages have support for that yet.

@awalterschulze
Copy link
Member

Yes this almost exactly what the Any type does.
Hmmm
If golang/protobuf rather registers a new function

proto.RegisterMessage(func () proto.Message {
   return &generatedType{}
})

Then you would simply be able to call the function.
Maybe you can take this issue up with them.
If they change it, then we can merge it into gogoprotobuf.

@bcmills
Copy link

bcmills commented Jan 24, 2017

I do know about protobuf "Any" types, but AFAIK, not all languages have support for that yet.

Any is a regular proto3 message type (defined in a .proto file): any language which supports proto3 at all should be compatible with it.

The only thing special about Any is that the proto runtime library for most languages has extra decoding support. (For Go, that's the ptypes package.)

@rogeralsing
Copy link
Contributor Author

Ok, I finally had some luck using Any type.
It is however far slower than what we have now. I would assume its the size of the DynamicAny or something that cost allocation time.

Our benchmarks dropped from 1.85 mil msg/sec to 1.1 mil msg/sec (nonsense benchmarks but still)

That being said, I also tried the

proto.RegisterMessage(func () proto.Message {
   return &generatedType{}
})

Approach mentioned by @awalterschulze
This had a fairly decent impact in a good way.
Up from 1.85 mil msg/sec to 2.0 mil msg/sec
So 150k diff.

Right now I manually registered this for my types.
It would have been neat if that could be generated though

@awalterschulze
Copy link
Member

awalterschulze commented Jan 25, 2017 via email

@awalterschulze
Copy link
Member

awalterschulze commented Jan 25, 2017 via email

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants