• Peter Waldschmidt's avatar
    encoding/json: Remove extra allocation in scanner. · a13606e6
    Peter Waldschmidt authored
    When the scanner receives a non-whitespace character in stateEndTop,
    it creates an error message and caches it to return on the next
    transition. nextValue() uses the scanner to sub-scan for a value
    inside a larger JSON structure. Since stateEndTop is triggered
    *after* the ending byte, whatever character immediately follows the
    sub-value gets pulled into the scanner's state machine as well.
    Even though it is not used and doesn't cause an error, it does
    cause the state machine to allocate an error that will never be used.
    
    The fix is to probe the state machine with whitespace after
    scanEndObject or scanEndArray to see if the next character would
    result in a scanEnd state transition. If so, we can return right
    away without processing the next character and avoid triggering
    an allocation.
    
    benchmark                       old ns/op     new ns/op     delta
    BenchmarkCodeEncoder            17022194      16611336      -2.41%
    BenchmarkCodeMarshal            18443250      18090144      -1.91%
    BenchmarkCodeDecoder            61502053      61010936      -0.80%
    BenchmarkCodeUnmarshal          61410829      60363605      -1.71%
    BenchmarkCodeUnmarshalReuse     59124836      58361772      -1.29%
    BenchmarkUnmarshalString        602           603           +0.17%
    BenchmarkUnmarshalFloat64       535           537           +0.37%
    BenchmarkUnmarshalInt64         482           482           +0.00%
    BenchmarkIssue10335             1206          799           -33.75%
    BenchmarkSkipValue              17605751      18355391      +4.26%
    BenchmarkEncoderEncode          612           604           -1.31%
    
    benchmark                  old MB/s     new MB/s     speedup
    BenchmarkCodeEncoder       114.00       116.82       1.02x
    BenchmarkCodeMarshal       105.21       107.27       1.02x
    BenchmarkCodeDecoder       31.55        31.81        1.01x
    BenchmarkCodeUnmarshal     31.60        32.15        1.02x
    BenchmarkSkipValue         111.63       107.07       0.96x
    
    benchmark                  old allocs     new allocs     delta
    BenchmarkIssue10335        11             4              -63.64%
    BenchmarkEncoderEncode     2              2              +0.00%
    
    benchmark                  old bytes     new bytes     delta
    BenchmarkIssue10335        376           272           -27.66%
    BenchmarkEncoderEncode     40            40            +0.00%
    
    Fixes #10335
    
    Change-Id: I3d4f2b67f7a038adfb33ba48bb6b680f528baf18
    Reviewed-on: https://go-review.googlesource.com/9074Reviewed-by: 's avatarRuss Cox <rsc@golang.org>
    a13606e6
scanner.go 16.6 KB