-
Notifications
You must be signed in to change notification settings - Fork 192
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
confused by Unmarshaler interface, could docs be extended a bit? #154
Comments
The only special feature of The first thing I'd recommend is using Also, I notice there are at least a couple fields in that data structure that use strings with only a few known values. You could replace those fields with interned strings so as not to allocate a new one each time it is decoded: type InternedString int
const (
_ InternedString = iota
InternedFoo
InternedBar
InternedBaz
)
func (i *InternedString) UnmarshalMsg(b []byte) ([]byte, error) {
o, s, err := ReadStringZC(b)
if err != nil {
return b, err
}
switch msgp.UnsafeString(s) {
case "foo":
*i = InternedFoo
case "bar":
*i = InternedBar
case "baz":
*i = InternedBaz
default:
return b, fmt.Errorf("unknown string %s", string(s))
}
return o, nil
} Let me know how that works for you. Cheers, |
Thanks Phil,
can i do this while retaining compatibility with messages based on the previous code? i would like to try this but i'm worried about breaking parsing of older messages. re your suggested code. i presume i would write the type declaration and define those consts, and then the UnmarshalMsg would be automatically generated like that, right? or do i have to provide that? |
You would have to provide the interning manually. But yes, if you can afford to make those strings |
Hi,
I have an app where about half of the alloc space is coming from
_, err = out.UnmarshalMsg(b)
(where b is a pre-existing byteslice i want to decode) and it's triggering GC too much.I have read https://github.com/tinylib/msgp/wiki/Getting-Started a couple times, specifically the section on the Marshaler and Unmarshaler interfaces. The former is pretty clear but i'm struggling with the latter. it's described as "simply the converse" and talks about how you can use the return value in a clever way. But it doesn't really mention anything about the input slice. is there anything noteworthy about it? Especially in context of zero-allocation?
For example am i supposed to supply an input slice that uses the len to cover the region of data to decode, but additional cap as temporary space for decoding? Or is it ok for cap to == len because it doesn't really need "temporary" space?
for the record, most of the allocations are seeing are due to ReadStringBytes (#145)
but i'm also seeing some others like
which i wonder if they can be avoided?
(this is while unmarshaling a MetricDataArray, which is defined in https://github.com/raintank/raintank-metric/blob/master/schema/metric.go)
thanks!
The text was updated successfully, but these errors were encountered: