Skip to content

Commit 09c4cb6

Browse files
committed
add trustMarshaler option to JSON encoder aimed at improving precomputed performance.
1 parent 5b31021 commit 09c4cb6

File tree

2 files changed

+28
-8
lines changed

2 files changed

+28
-8
lines changed

src/encoding/json/encode.go

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -349,6 +349,8 @@ type encOpts struct {
349349
quoted bool
350350
// escapeHTML causes '<', '>', and '&' to be escaped in JSON strings.
351351
escapeHTML bool
352+
// trustMarshaler causes Marshaler not to be compacted, escaped and validated.
353+
trustMarshaler bool
352354
}
353355

354356
type encoderFunc func(e *encodeState, v reflect.Value, opts encOpts)
@@ -462,8 +464,12 @@ func marshalerEncoder(e *encodeState, v reflect.Value, opts encOpts) {
462464
}
463465
b, err := m.MarshalJSON()
464466
if err == nil {
465-
// copy JSON into buffer, checking validity.
466-
err = compact(&e.Buffer, b, opts.escapeHTML)
467+
// copy JSON in to buffer.
468+
if opts.trustMarshaler {
469+
_, err = e.Buffer.Write(b)
470+
} else {
471+
err = compact(&e.Buffer, b, opts.escapeHTML)
472+
}
467473
}
468474
if err != nil {
469475
e.error(&MarshalerError{v.Type(), err, "MarshalJSON"})
@@ -479,8 +485,12 @@ func addrMarshalerEncoder(e *encodeState, v reflect.Value, opts encOpts) {
479485
m := va.Interface().(Marshaler)
480486
b, err := m.MarshalJSON()
481487
if err == nil {
482-
// copy JSON into buffer, checking validity.
483-
err = compact(&e.Buffer, b, opts.escapeHTML)
488+
// copy JSON in to buffer.
489+
if opts.trustMarshaler {
490+
_, err = e.Buffer.Write(b)
491+
} else {
492+
err = compact(&e.Buffer, b, opts.escapeHTML)
493+
}
484494
}
485495
if err != nil {
486496
e.error(&MarshalerError{v.Type(), err, "MarshalJSON"})

src/encoding/json/stream.go

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -179,9 +179,10 @@ func nonSpace(b []byte) bool {
179179

180180
// An Encoder writes JSON values to an output stream.
181181
type Encoder struct {
182-
w io.Writer
183-
err error
184-
escapeHTML bool
182+
w io.Writer
183+
err error
184+
escapeHTML bool
185+
trustMarshaler bool
185186

186187
indentBuf *bytes.Buffer
187188
indentPrefix string
@@ -203,7 +204,7 @@ func (enc *Encoder) Encode(v interface{}) error {
203204
return enc.err
204205
}
205206
e := newEncodeState()
206-
err := e.marshal(v, encOpts{escapeHTML: enc.escapeHTML})
207+
err := e.marshal(v, encOpts{escapeHTML: enc.escapeHTML, trustMarshaler: enc.trustMarshaler})
207208
if err != nil {
208209
return err
209210
}
@@ -254,6 +255,15 @@ func (enc *Encoder) SetEscapeHTML(on bool) {
254255
enc.escapeHTML = on
255256
}
256257

258+
// SetTrustMarshaler specifies whether fields implement Marshaler
259+
// should be computed such as escape, compact.
260+
// The default behavior is to run compact on output of Marshaler.
261+
// SetTrustMarshaler(true) just copies output of Marshaler
262+
// and makes better performance.
263+
func (enc *Encoder) SetTrustMarshaler(on bool) {
264+
enc.trustMarshaler = on
265+
}
266+
257267
// RawMessage is a raw encoded JSON value.
258268
// It implements Marshaler and Unmarshaler and can
259269
// be used to delay JSON decoding or precompute a JSON encoding.

0 commit comments

Comments
 (0)