Skip to content

Commit 34a512f

Browse files
committed
internal/core/adt: avoid more allocations when LogEval is disabled
Benchmarking Judson's private project in Unity with benchcmd as follows: benchcmd -n 6 ExportJudsonOpendef bash -c 'CUE_DEBUG=opendef cue export -t variant=test -t shard=0 -e files ./structure >/dev/null' I'm using CUE_DEBUG=opendef as closedness tracking causes significantly worse performance due to https://cuelang.org/issue/3881, to the point that measuring enough data points for comparing benchmark results would take tens of minutes. The results are however promising, as his CPU profile showed that garbage collection was about 30% of CPU usage overall, and the memory profile showed that a good portion of those allocations came from Logf calls which aren't meant to do anything by default: │ old │ new │ │ sec/op │ sec/op vs base │ ExportJudsonOpendef 9.800 ± 2% 9.158 ± 4% -6.55% (p=0.002 n=6) │ old │ new │ │ user-sec/op │ user-sec/op vs base │ ExportJudsonOpendef 18.05 ± 14% 17.48 ± 11% ~ (p=0.818 n=6) │ old │ new │ │ sys-sec/op │ sys-sec/op vs base │ ExportJudsonOpendef 1.315 ± 10% 1.328 ± 16% ~ (p=0.937 n=6) │ old │ new │ │ peak-RSS-bytes │ peak-RSS-bytes vs base │ ExportJudsonOpendef 9.831Gi ± 5% 9.699Gi ± 6% ~ (p=0.394 n=6) Signed-off-by: Daniel Martí <[email protected]> Change-Id: I42b925c90a5baf02bbaca4af745357af1b477ade Reviewed-on: https://review.gerrithub.io/c/cue-lang/cue/+/1213383 Unity-Result: CUE porcuepine <[email protected]> TryBot-Result: CUEcueckoo <[email protected]> Reviewed-by: Marcel van Lohuizen <[email protected]>
1 parent 8fef4d3 commit 34a512f

File tree

4 files changed

+17
-5
lines changed

4 files changed

+17
-5
lines changed

Diff for: internal/core/adt/log.go

+8-2
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,8 @@ func (c *OpContext) Un(s nestString, id int) {
6969
// The first argument must be the function name.
7070
func (c *OpContext) Indentf(v *Vertex, format string, args ...any) (s nestString, id int) {
7171
if c.LogEval == 0 {
72+
// The Go compiler as of 1.24 is not very clever with no-op function calls;
73+
// any arguments passed to ...args above escape to the heap and allocate.
7274
panic("avoid calling OpContext.Indentf when logging is disabled to prevent overhead")
7375
}
7476
name := strings.Split(format, "(")[0]
@@ -101,7 +103,9 @@ func (c *OpContext) RewriteArgs(args ...interface{}) {
101103

102104
func (c *OpContext) Logf(v *Vertex, format string, args ...interface{}) {
103105
if c.LogEval == 0 {
104-
return
106+
// The Go compiler as of 1.24 is not very clever with no-op function calls;
107+
// any arguments passed to ...args above escape to the heap and allocate.
108+
panic("avoid calling OpContext.Logf when logging is disabled to prevent overhead")
105109
}
106110
w := &strings.Builder{}
107111

@@ -218,7 +222,9 @@ func (n *nodeContext) logDoDisjunct() *disjunctInfo {
218222

219223
d.disjunctID = int(c.stats.Disjuncts)
220224

221-
n.Logf("====== Do DISJUNCT %v & %v ======", d.lhs, d.rhs)
225+
if n.ctx.LogEval > 0 {
226+
n.Logf("====== Do DISJUNCT %v & %v ======", d.lhs, d.rhs)
227+
}
222228

223229
return d
224230
}

Diff for: internal/core/adt/states.go

+3-1
Original file line numberDiff line numberDiff line change
@@ -260,7 +260,9 @@ var schedConfig = taskContext{
260260
func stateCompletions(s *scheduler) condition {
261261
x := s.completed
262262
v := s.node.node
263-
s.node.Logf("=== stateCompletions: %v %v", v.Label, s.completed)
263+
if s.node.ctx.LogEval > 0 {
264+
s.node.Logf("=== stateCompletions: %v %v", v.Label, s.completed)
265+
}
264266
if x.meets(allAncestorsProcessed) {
265267
x |= conditionsUsingCounters &^ s.provided
266268
// If we have a pending or constraint arc, a sub arc may still cause the

Diff for: internal/core/adt/tasks.go

+3-1
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,9 @@ func processResolver(ctx *OpContext, t *task, mode runMode) {
109109
}
110110
arc = arc.DerefNonDisjunct()
111111

112-
ctx.Logf(t.node.node, "RESOLVED %v to %v %v", r, arc.Label, fmt.Sprintf("%p", arc))
112+
if ctx.LogEval > 0 {
113+
ctx.Logf(t.node.node, "RESOLVED %v to %v %v", r, arc.Label, fmt.Sprintf("%p", arc))
114+
}
113115
// TODO: consider moving after markCycle or removing.
114116
d := arc.DerefDisjunct()
115117

Diff for: internal/core/adt/unify.go

+3-1
Original file line numberDiff line numberDiff line change
@@ -761,7 +761,9 @@ func (v *Vertex) lookup(c *OpContext, pos token.Pos, f Feature, flags combinedFl
761761

762762
v = v.DerefValue()
763763

764-
c.Logf(c.vertex, "LOOKUP %v", f)
764+
if c.LogEval > 0 {
765+
c.Logf(c.vertex, "LOOKUP %v", f)
766+
}
765767

766768
state := v.getState(c)
767769
if state != nil {

0 commit comments

Comments
 (0)