Closed 2opremio closed 8 years ago
Good idea per the WriteByte optimization. Will do. simpleIoEncWriterWriter is not scoped, so we can cache a 1-element byte array, and use it all the time when writing a byte.
We can't do anything for msgpack.DecodeString. We can't control who calls DecodeString, so doing a stringView at that point is not an option. Consequently, we have to do a conversion (which implicitly does an allocation and copy).
Fix coming in a few.
BTW, bw is nil because the Writer passed to Encode in not a ByteWriter.
Thanks!!!
On Sunday, February 21, 2016, Ugorji Nwoke notifications@github.com wrote:
Closed #143 https://github.com/ugorji/go/issues/143 via 03b46f3 https://github.com/ugorji/go/commit/03b46f3d7a8e0457836a5ecd906b4961a5815a63 .
— Reply to this email directly or view it on GitHub https://github.com/ugorji/go/issues/143#event-557890674.
One final note regarding (*simpleIoEncWriterWriter) WriteString()
. I have taken a closer look at the alloc_objects
profile and most of the calls to (*simpleIoEncWriterWriter) WriteString()
(if not all) are coming from types for which Selfer
s were generated with codecgen
-u
(see for instance (Node*).CodecEncodeSelf
in the call graph below).
I know that (*simpleIoEncWriterWriter) WriteString()
will stop generating garbage when compiling github.com/ugorji/go/codec
with -tags unsafe
, which makes sense for reflection-based encoding. However, wouldn't it make sense to create a specialized unsafe-version of WriteString()
function so that the code generated by codecgen
in unsafe mode can invoke it regardless of whether the codec was compiled with -tags unsafe
or not?
go tool pprof -focus '.*WriteString.*' -alloc_objects -png pprof.localhost.4041.alloc_objects.alloc_space.003.pb.gz > probe.png
You can find the generated code for most (if not all) the types involved here at: https://gist.github.com/2opremio/0956c1e883b89eba71a9
We can't do anything for msgpack.DecodeString. We can't control who calls DecodeString, so doing a stringView at that point is not an option. Consequently, we have to do a conversion (which implicitly does an allocation and copy).
I have also taken a deeper look at the Scope app alloc_objects
graph, and most (if not all) the calls to msgpack.DecodeString
come from Selfer
s generated by codecgen -u
. Isn't it reasonable to provide a specialized unsafe-version of msgpack.DecodeString
to be invoked in that case?
This case is particularly bad, since it won't even get fixed when compiling with -tags unsafe
. Again, this isn't where our garbage-bottleneck lies but others may benefit from this optimization.
$ go tool pprof -png -alloc_objects -focus '.*DecodeString.*' pprof.localhost.4040.alloc_objects.alloc_space.001.pb.gz > app.png
Those calls are likely reading a value to set a struct field e.g. struct {S string}. There's no magic workaround: you have to read the value as []byte, and then copy that to a string and set it. We can only do unsafe when we know that the string is intermittent, and within our control. E.g. if we are are looking at the string so that we can do a switch/case match, or if we are just passing it into a WriteString() method, etc.
On Sun, Feb 21, 2016 at 2:17 PM, Alfonso Acosta notifications@github.com wrote:
We can't do anything for msgpack.DecodeString. We can't control who calls DecodeString, so doing a stringView at that point is not an option. Consequently, we have to do a conversion (which implicitly does an allocation and copy).
I have also taken a deeper look at the Scope app alloc_objects graph, and most (if not all) the calls to msgpack.DecodeString come from Selfers generated by codecgen -u. Isn't it reasonable to provide a specialized unsafe-version of msgpack.DecodeString ?
$ go tool pprof -png -alloc_objects -focus '.DecodeString.' pprof.localhost.4040.alloc_objects.alloc_space.001.pb.gz > app.png
[image: probe] https://cloud.githubusercontent.com/assets/2362916/13204757/af43e74a-d8cf-11e5-84b6-d965c273214f.png
— Reply to this email directly or view it on GitHub https://github.com/ugorji/go/issues/143#issuecomment-186893966.
After migrating the codecs of https://github.com/weaveworks/scope/ to github.com/ugorji/go I am looking at the garbage generated:
(This comes from the Scope probe, https://github.com/weaveworks/scope/issues/812#issuecomment-186337744 for the raw profile file and a complete graph)
It seems we could win a bit by optimizing
codec.(*simpleIoEncWriterWriter).WriteByte()
(and compiling with-tags unsafe
). @ugorji Do you know what is causing bw to be nil? If that's not easily solvable, could you at least cache that slice?Also, (although it has a lower impact for us) it may be worth optimizing
codec.(*msgpackDecDriver).DecodeString()
:(This comes from the Scope app, see https://github.com/weaveworks/scope/issues/854#issuecomment-186352500 for the raw profile file and a complete graph).