detached b4521f0

bench_test.go RawHistoryFolder

1package kvconf
2
3import (
4	"context"
5	"fmt"
6	"os"
7	"strings"
8	"testing"
9	"time"
10)
11
12type benchConfig struct {
13	Theme   string            `kv:"theme" oneof:"auto|dark|light"`
14	Enabled bool              `kv:"enabled"`
15	Count   int               `kv:"count" min:"0" max:"1000"`
16	After   time.Duration     `kv:"lock.after,off"`
17	Ratio   float64           `kv:"ratio"`
18	Tags    []string          `kv:"tags"`
19	Color   string            `kv:"border.color"`
20	Binds   map[string]string `kv:"bind.*"`
21	Outputs map[string]output `kv:"output.*"`
22}
23
24// benchFile is a realistic config: ~100 lines with comments, binds and
25// per-output settings.
26var benchFile = func() []byte {
27	var b strings.Builder
28	b.WriteString("# a comment\ntheme = dark\nenabled = on\ncount = 42\nlock.after = 5m\nratio = 1.5\n")
29	b.WriteString("tags = a, b, c\nborder.color = #ff8800  # orange\n\n")
30	for i := range 60 {
31		fmt.Fprintf(&b, "bind.cmd+%d = spawn \"foot -e app%d\"\n", i, i)
32	}
33	for i := range 8 {
34		fmt.Fprintf(&b, "output.DP-%d.scale = 1.25\noutput.DP-%d.hdr = off\noutput.DP-%d.sdr-brightness = 203\n", i, i, i)
35	}
36	return []byte(b.String())
37}()
38
39func BenchmarkParse(b *testing.B) {
40	b.ReportAllocs()
41	b.SetBytes(int64(len(benchFile)))
42	for b.Loop() {
43		if _, _, err := ParseBytes(benchFile, Options{}); err != nil {
44			b.Fatal(err)
45		}
46	}
47}
48
49func BenchmarkUnmarshal(b *testing.B) {
50	b.ReportAllocs()
51	b.SetBytes(int64(len(benchFile)))
52	for b.Loop() {
53		var c benchConfig
54		if w, err := Unmarshal(benchFile, &c, Options{}); err != nil || len(w) > 0 {
55			b.Fatal(w, err)
56		}
57	}
58}
59
60func BenchmarkDecodeScalars(b *testing.B) {
61	entries, _, _ := ParseBytes([]byte("theme = dark\nenabled = on\ncount = 42\nlock.after = 5m\nratio = 1.5\n"), Options{})
62	b.ReportAllocs()
63	for b.Loop() {
64		var c benchConfig
65		if _, err := Decode(entries, &c, Options{}); err != nil {
66			b.Fatal(err)
67		}
68	}
69}
70
71func BenchmarkMarshal(b *testing.B) {
72	var c benchConfig
73	if _, err := Unmarshal(benchFile, &c, Options{}); err != nil {
74		b.Fatal(err)
75	}
76	b.ReportAllocs()
77	for b.Loop() {
78		if _, err := Marshal(&c); err != nil {
79			b.Fatal(err)
80		}
81	}
82}
83
84// BenchmarkWatchEvent measures one change seen by the watcher: the event,
85// its classification and the debounced report.
86func BenchmarkWatchEvent(b *testing.B) {
87	dir := b.TempDir()
88	path := dir + "/config"
89	if err := os.WriteFile(path, benchFile, 0o600); err != nil {
90		b.Fatal(err)
91	}
92	out := make(chan struct{}, 1)
93	ctx, cancel := context.WithCancel(context.Background())
94	defer cancel()
95	ready := make(chan struct{})
96	go func() { _ = Watch(ctx, path, WatchOptions{Debounce: -1, Ready: ready}, out) }()
97	<-ready
98	f, err := os.OpenFile(path, os.O_WRONLY, 0)
99	if err != nil {
100		b.Fatal(err)
101	}
102	defer f.Close()
103	b.ReportAllocs()
104	for b.Loop() {
105		if _, err := f.WriteAt([]byte{'#'}, 0); err != nil {
106			b.Fatal(err)
107		}
108		<-out
109	}
110}
111
112func BenchmarkSet(b *testing.B) {
113	values := map[string]*string{"output.DP-3.scale": ptr("2")}
114	b.ReportAllocs()
115	for b.Loop() {
116		if _, err := Set(benchFile, values); err != nil {
117			b.Fatal(err)
118		}
119	}
120}

Keyboard shortcuts

Single-key shortcuts are on. ctrl k and esc work whatever this says.

ctrl k :
go to a section, branch, tag, file or repository
?
this list
j k
move the row cursor down / up
enter
open the row under the cursor; on Files, a directory opens or closes in place
↑ ↓ ← → home end
in the file tree (focus on a row): previous / next row, close / open a directory or go to its parent / first entry, first / last row. They never open a file
l h
on Files: open a directory or a file / close a directory or go up to its parent, then to the parent page. Elsewhere: into the side panel (on a merge request, its files) / back to the content; there j k move between its controls
g g G
first / last row
/
filter the list; on Files, find a file anywhere in the repository (esc clears, enter opens the best match)
b
switch branch or tag
g s g f g c g b g m g i g r g a
tabs: summary, files, commits, branches & tags, merge requests, issues, releases, actions (when available)
g h
home
w
wide mode: use the whole width of the screen, or not (remembered)
y
copy a permalink pinned to the commit
d u x
diff: split / unified / collapse or expand all
e E
diff: the whole file in view / every file, with the lines the hunks hide
n
merge request: next note in the diff
esc
close a dialog, leave a field

Branches 1

Tags 3

↑↓ moveenter openesc close