-
Notifications
You must be signed in to change notification settings - Fork 11
Add custom marshal implementation for protobuf value type #17
Add custom marshal implementation for protobuf value type #17
Conversation
Is using https://pkg.go.dev/google.golang.org/protobuf/types/known/structpb#Struct.AsMap followed by the stdlib Marshal any better? Is this a deterministic in how it serializes? |
@cmacknz performance is about the same, but it uses considerably more memory:
Trying to bypass/reimplement the behavior of the stdlib |
The more I look over pprof and look at potential improvements, the more I think that any performance improvements might come with a stability tradeoff, as we'd essentially be re-implementing a ton of the stdlib json marshal backend, meaning we'd need to implement all the error handling and edge cases that come with it. |
I learned today that APM Server implemented their own low level JSON serialization package to speed things up. https://github.com/elastic/go-fastjson We could explore using that (or another json package to help this out). I don't know that we need to do all of the optimizations in this PR though. |
Yah, agreed, it's easy to get carried away with optimizations like this, particularly before we've tested the entire shipper. |
Alright, using the fastjson libraries gives us a slight improvement:
|
// MarshalJSON implements the JSON interface for the value type | ||
func (val *Value) MarshalJSON() ([]byte, error) { | ||
// MarshalFastJSON implements the JSON interface for the value type | ||
func (val *Value) MarshalFastJSON(w *fastjson.Writer) error { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I can't see test coverage for any of these functions, probably because they are in a separate package from the tests in helpers.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's get this integrated into the shipper so we can run a proper performance test.
Co-authored-by: Craig MacKenzie <craig.mackenzie@elastic.co>
Should fix elastic/elastic-agent-shipper#240
This adds a custom
MarshalJSON()
method to the various*value
types used by the gRPC API, so we can properly marshal the event in a way elasticsearch will expect, and that should be equivalent to how how beats wound send events normally without the shipper in between.I included a benchmark test in here as well, as right now it doesn't compare too favorably to marshalling from a hashmap:
I've taken a few cracks at optimizing it, but the stdlib json
Marshal()
is so optimized that I haven't been able to make much progress.