Skip to content

Commit

Permalink
cue: avoid repeated work in Value.MarshalJSON with lists
Browse files Browse the repository at this point in the history
Value.appendJSON already switches on the value kind and applies defaults
so repeating that work in Value.List is a waste.
Moreover, we already have an OpContext we can reuse.

                            │     old     │                new                │
                            │   sec/op    │   sec/op     vs base              │
    LargeValueMarshalJSON-8   6.092m ± 1%   5.488m ± 1%  -9.91% (p=0.002 n=6)

                            │     old      │                 new                 │
                            │     B/op     │     B/op      vs base               │
    LargeValueMarshalJSON-8   3.445Mi ± 0%   2.360Mi ± 0%  -31.49% (p=0.002 n=6)

                            │     old     │                new                 │
                            │  allocs/op  │  allocs/op   vs base               │
    LargeValueMarshalJSON-8   58.26k ± 0%   52.25k ± 0%  -10.31% (p=0.002 n=6)

Updates #2470.

Signed-off-by: Daniel Martí <[email protected]>
Change-Id: Ie180170d277c99a996a8e38a8a9e1c0b13e28154
Reviewed-on: https://review.gerrithub.io/c/cue-lang/cue/+/1202101
TryBot-Result: CUEcueckoo <[email protected]>
Reviewed-by: Roger Peppe <[email protected]>
Unity-Result: CUE porcuepine <[email protected]>
  • Loading branch information
mvdan committed Oct 2, 2024
1 parent 8009b56 commit 8a6ed2c
Showing 1 changed file with 8 additions and 2 deletions.
10 changes: 8 additions & 2 deletions cue/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -944,7 +944,7 @@ func (v Value) appendJSON(ctx *adt.OpContext, b []byte) ([]byte, error) {
b2, err := json.Marshal(x.(*adt.Bytes).B)
return append(b, b2...), err
case adt.ListKind:
i, _ := v.List()
i := v.mustList(ctx)
return listAppendJSON(b, &i)
case adt.StructKind:
obj, err := v.structValData(ctx)
Expand Down Expand Up @@ -1327,13 +1327,19 @@ func (v Value) List() (Iterator, error) {
if err := v.checkKind(ctx, adt.ListKind); err != nil {
return Iterator{idx: v.idx, ctx: ctx}, v.toErr(err)
}
return v.mustList(ctx), nil
}

// mustList is like [Value.List], but reusing ctx and leaving it to the caller
// to apply defaults and check the kind.
func (v Value) mustList(ctx *adt.OpContext) Iterator {
arcs := []*adt.Vertex{}
for _, a := range v.v.Elems() {
if a.Label.IsInt() {
arcs = append(arcs, a)
}
}
return Iterator{idx: v.idx, ctx: ctx, val: v, arcs: arcs}, nil
return Iterator{idx: v.idx, ctx: ctx, val: v, arcs: arcs}
}

// Null reports an error if v is not null.
Expand Down

0 comments on commit 8a6ed2c

Please sign in to comment.