• Daniel Martí's avatar
    encoding/json: index names for the struct decoder · 7e08c7f4
    Daniel Martí authored
    In the common case, structs have a handful of fields and most inputs
    match struct field names exactly.
    
    The previous code would do a linear search over the fields, stopping at
    the first exact match, and otherwise using the first case insensitive
    match.
    
    This is unfortunate, because it means that for the common case, we'd do
    a linear search with bytes.Equal. Even for structs with only two or
    three fields, that is pretty wasteful.
    
    Worse even, up until the exact match was found via the linear search,
    all previous fields would run their equalFold functions, which aren't
    cheap even in the simple case.
    
    Instead, cache a map along with the field list that indexes the fields
    by their name. This way, a case sensitive field search doesn't involve a
    linear search, nor does it involve any equalFold func calls.
    
    This patch should also slightly speed up cases where there's a case
    insensitive match but not a case sensitive one, as then we'd avoid
    calling bytes.Equal on all the fields. Though that's not a common case,
    and there are no benchmarks for it.
    
    name           old time/op    new time/op    delta
    CodeDecoder-8    11.0ms ± 0%    10.6ms ± 1%  -4.42%  (p=0.000 n=9+10)
    
    name           old speed      new speed      delta
    CodeDecoder-8   176MB/s ± 0%   184MB/s ± 1%  +4.62%  (p=0.000 n=9+10)
    
    name           old alloc/op   new alloc/op   delta
    CodeDecoder-8    2.28MB ± 0%    2.28MB ± 0%    ~     (p=0.725 n=10+10)
    
    name           old allocs/op  new allocs/op  delta
    CodeDecoder-8     76.9k ± 0%     76.9k ± 0%    ~     (all equal)
    
    Updates #28923.
    
    Change-Id: I9929c1f06c76505e5b96914199315dbdaae5dc76
    Reviewed-on: https://go-review.googlesource.com/c/go/+/172918
    Run-TryBot: Daniel Martí <mvdan@mvdan.cc>
    TryBot-Result: Gobot Gobot <gobot@golang.org>
    Reviewed-by: default avatarBrad Fitzpatrick <bradfitz@golang.org>
    7e08c7f4
encode.go 34.4 KB