Draw groups: one reference draw per render, a drawGroup option, and a record's fences at load #16

Merged
lilleman merged 14 commits from draw-groups into main 2026-09-16 10:45:45 +02:00
Showing only changes of commit 0443ecdf13 - Show all commits
+26
View File
@@ -52,6 +52,32 @@ func TestNoRenderAllocRegression(t *testing.T) {
} }
// A record's fences read the compiled tree, so they belong to New, not to a draw. // A record's fences read the compiled tree, so they belong to New, not to a draw.
// A reference path read across a repeat, and one read in a named draw group. The repeat
// prices both measures that keep a render's draw set off the heap — inlining expandAnew
// into render's loop, or keying a draw group's map with the scope's own string, costs an
// allocation an iteration — while the draw group holds the group path's own count.
func TestNoReferenceAllocRegression(t *testing.T) {
word := `{"format":"{w}","w":["alpha","beta","gamma","delta"]}`
for _, s := range []struct {
name, json string
base float64
}{
{"a repeat of a reference path", `{"format":"{r}","r":{"format":"{/word.w}","repeat":20,"separator":", "}}`, 66},
{"a named draw group", `{"format":"{a}","a":{"format":"{/word.w}","drawGroup":"g"}}`, 11},
} {
f, err := New(WithoutShippedData(), WithDataFS(fstest.MapFS{
"word.json": {Data: []byte(word)},
"x.json": {Data: []byte(s.json)},
}))
if err != nil {
t.Fatalf("New(%s): %v", s.name, err)
}
if allocs := testing.AllocsPerRun(10000, func() { f.Fake("x") }); allocs > s.base*1.10 {
t.Errorf("%s: %.1f allocs/op regressed past %.1f (baseline %.1f + 10%%); a draw set reaching the heap is the usual cause", s.name, allocs, s.base*1.10, s.base)
}
}
}
func TestNoRecordAllocRegression(t *testing.T) { func TestNoRecordAllocRegression(t *testing.T) {
for _, s := range []struct{ name, json string }{ for _, s := range []struct{ name, json string }{
{"record 3 columns", `{"format":"","a":"x","b":"y","c":"z"}`}, {"record 3 columns", `{"format":"","a":"x","b":"y","c":"z"}`},