mirror of
https://github.com/golang/go
synced 2024-11-23 18:40:03 -07:00
Revert "encoding/json: reduce unmarshal mallocs for unmapped fields"
This reverts commit df68afd07c
(https://golang.org/cl/33276)
Reason for revert: made other benchmarks worse
Fixes #20693 (details)
Updates #17914
Updates #10335
Change-Id: If451b620803ccb0536b89c76c4353d2185d57d7e
Reviewed-on: https://go-review.googlesource.com/47211
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Russ Cox <rsc@golang.org>
This commit is contained in:
parent
68e1b3e361
commit
912bb817b0
@ -361,40 +361,47 @@ func (d *decodeState) scanWhile(op int) int {
|
|||||||
return newOp
|
return newOp
|
||||||
}
|
}
|
||||||
|
|
||||||
// discardObject and discardArray are dummy data targets
|
|
||||||
// used by the (*decodeState).value method, which
|
|
||||||
// accepts a zero reflect.Value to discard a value.
|
|
||||||
// The (*decodeState).object and (*decodeState).array methods,
|
|
||||||
// however, require a valid reflect.Value destination.
|
|
||||||
// These are the target values used when the caller of value
|
|
||||||
// wants to skip a field.
|
|
||||||
//
|
|
||||||
// Because these values refer to zero-sized objects
|
|
||||||
// and thus can't be mutated, they're safe for concurrent use
|
|
||||||
// by different goroutines unmarshalling skipped fields.
|
|
||||||
var (
|
|
||||||
discardObject = reflect.ValueOf(struct{}{})
|
|
||||||
discardArray = reflect.ValueOf([0]interface{}{})
|
|
||||||
)
|
|
||||||
|
|
||||||
// value decodes a JSON value from d.data[d.off:] into the value.
|
// value decodes a JSON value from d.data[d.off:] into the value.
|
||||||
// It updates d.off to point past the decoded value. If v is
|
// it updates d.off to point past the decoded value.
|
||||||
// invalid, the JSON value is discarded.
|
|
||||||
func (d *decodeState) value(v reflect.Value) {
|
func (d *decodeState) value(v reflect.Value) {
|
||||||
|
if !v.IsValid() {
|
||||||
|
_, rest, err := nextValue(d.data[d.off:], &d.nextscan)
|
||||||
|
if err != nil {
|
||||||
|
d.error(err)
|
||||||
|
}
|
||||||
|
d.off = len(d.data) - len(rest)
|
||||||
|
|
||||||
|
// d.scan thinks we're still at the beginning of the item.
|
||||||
|
// Feed in an empty string - the shortest, simplest value -
|
||||||
|
// so that it knows we got to the end of the value.
|
||||||
|
if d.scan.redo {
|
||||||
|
// rewind.
|
||||||
|
d.scan.redo = false
|
||||||
|
d.scan.step = stateBeginValue
|
||||||
|
}
|
||||||
|
d.scan.step(&d.scan, '"')
|
||||||
|
d.scan.step(&d.scan, '"')
|
||||||
|
|
||||||
|
n := len(d.scan.parseState)
|
||||||
|
if n > 0 && d.scan.parseState[n-1] == parseObjectKey {
|
||||||
|
// d.scan thinks we just read an object key; finish the object
|
||||||
|
d.scan.step(&d.scan, ':')
|
||||||
|
d.scan.step(&d.scan, '"')
|
||||||
|
d.scan.step(&d.scan, '"')
|
||||||
|
d.scan.step(&d.scan, '}')
|
||||||
|
}
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
switch op := d.scanWhile(scanSkipSpace); op {
|
switch op := d.scanWhile(scanSkipSpace); op {
|
||||||
default:
|
default:
|
||||||
d.error(errPhase)
|
d.error(errPhase)
|
||||||
|
|
||||||
case scanBeginArray:
|
case scanBeginArray:
|
||||||
if !v.IsValid() {
|
|
||||||
v = discardArray
|
|
||||||
}
|
|
||||||
d.array(v)
|
d.array(v)
|
||||||
|
|
||||||
case scanBeginObject:
|
case scanBeginObject:
|
||||||
if !v.IsValid() {
|
|
||||||
v = discardObject
|
|
||||||
}
|
|
||||||
d.object(v)
|
d.object(v)
|
||||||
|
|
||||||
case scanBeginLiteral:
|
case scanBeginLiteral:
|
||||||
@ -512,7 +519,8 @@ func (d *decodeState) array(v reflect.Value) {
|
|||||||
d.off--
|
d.off--
|
||||||
d.next()
|
d.next()
|
||||||
return
|
return
|
||||||
case reflect.Array, reflect.Slice:
|
case reflect.Array:
|
||||||
|
case reflect.Slice:
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -791,9 +799,7 @@ func (d *decodeState) literal(v reflect.Value) {
|
|||||||
d.off--
|
d.off--
|
||||||
d.scan.undo(op)
|
d.scan.undo(op)
|
||||||
|
|
||||||
if v.IsValid() {
|
d.literalStore(d.data[start:d.off], v, false)
|
||||||
d.literalStore(d.data[start:d.off], v, false)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// convertNumber converts the number literal s to a float64 or a Number
|
// convertNumber converts the number literal s to a float64 or a Number
|
||||||
|
Loading…
Reference in New Issue
Block a user