• Daniel Martí's avatar
    encoding/json: remove a branch in the structEncoder loop · c21ba224
    Daniel Martí authored
    Encoders like map and array can use the much cheaper "i > 0" check to
    see if we're not writing the first element. However, since struct fields
    support omitempty, we need to keep track of that separately.
    
    This is much more expensive - after calling the field encoder itself,
    and retrieving the field via reflection, this branch was the third most
    expensive piece of this field loop.
    
    Instead, hoist the branch logic outside of the loop. The code doesn't
    get much more complex, since we just delay the writing of each byte
    until the next iteration. Yet the performance improvement is noticeable,
    even when the struct types in CodeEncoder only have 2 and 7 fields,
    respectively.
    
    name           old time/op    new time/op    delta
    CodeEncoder-4    5.39ms ± 0%    5.31ms ± 0%  -1.37%  (p=0.010 n=4+6)
    
    name           old speed      new speed      delta
    CodeEncoder-4   360MB/s ± 0%   365MB/s ± 0%  +1.39%  (p=0.010 n=4+6)
    
    Updates #5683.
    
    Change-Id: I2662cf459e0dfd68e56fa52bc898a417e84266c2
    Reviewed-on: https://go-review.googlesource.com/131401
    Run-TryBot: Daniel Martí <mvdan@mvdan.cc>
    Reviewed-by: 's avatarBrad Fitzpatrick <bradfitz@golang.org>
    TryBot-Result: Gobot Gobot <gobot@golang.org>
    c21ba224
Name
Last commit
Last update
..
testdata Loading commit data...
bench_test.go Loading commit data...
decode.go Loading commit data...
decode_test.go Loading commit data...
encode.go Loading commit data...
encode_test.go Loading commit data...
example_marshaling_test.go Loading commit data...
example_test.go Loading commit data...
fold.go Loading commit data...
fold_test.go Loading commit data...
indent.go Loading commit data...
number_test.go Loading commit data...
scanner.go Loading commit data...
scanner_test.go Loading commit data...
stream.go Loading commit data...
stream_test.go Loading commit data...
tables.go Loading commit data...
tagkey_test.go Loading commit data...
tags.go Loading commit data...
tags_test.go Loading commit data...