cat / 012
clone

a spreadsheet for the terminal: lotus 1-2-3 looks, google sheets keys and formulas, one go binary

Benchmark replaying a 1000-action macro and a script's calls under -tags stress; read small ranges without scanning the sheet

Dami committed 74a7125
commit
74a712598c4003cd48a56912340aa0cb8d293aa7
parent
fc0deece2ba5bd5511bd86e79c9072c0f8cf9943
author
Dami <dami.etoile@gmail.com>
2 files changed, +106 -2
Ainternal/ui/macro_stress_test.go100++++++++++++++++++++++++++++++
Minternal/ui/macrohost.go8++-
A internal/ui/macro_stress_test.go +100 -0
@@ -0,0 +1,100 @@
1+//go:build stress2+3+package ui4+5+import (6+ "fmt"7+ "testing"8+9+ "github.com/FelineStateMachine/012/internal/macro"10+ "github.com/FelineStateMachine/012/internal/sheet"11+)12+13+// replayActions is a recording of n actions as a user makes them: entries14+// of numbers, text and formulas, moves between them, a selection and a15+// command now and then.16+func replayActions(n int, relative bool) []macro.Action {17+ out := make([]macro.Action, 0, n)18+ for i := 0; len(out) < n; i++ {19+ row := i/4 + 120+ switch i % 8 {21+ case 0:22+ out = append(out, macro.Call("enter", fmt.Sprint(i)))23+ case 1:24+ out = append(out, macro.Call("enter", "item "+fmt.Sprint(i)))25+ case 2:26+ a := macro.Call("enter", fmt.Sprintf("=A%d*2", row))27+ if relative {28+ a = a.With("origin", fmt.Sprintf("C%d", row))29+ }30+ out = append(out, a)31+ case 3:32+ out = append(out, macro.Call("extend", 2, 0))33+ case 4:34+ out = append(out, macro.Call("run", "format.bold"))35+ case 5, 6:36+ if relative {37+ out = append(out, macro.Call("move", 1, 0))38+ } else {39+ out = append(out, macro.Call("select", fmt.Sprintf("%s%d", sheet.ColName(i%8-4), row)))40+ }41+ case 7:42+ if relative {43+ out = append(out, macro.Call("move", -2, 1))44+ } else {45+ out = append(out, macro.Call("select", fmt.Sprintf("A%d", row+1)))46+ }47+ }48+ }49+ return out50+}51+52+// BenchmarkMacroReplay replays a 1000-action recorded macro through the53+// real path: the script on its own goroutine, each call served on the54+// model through Bubble Tea messages, all of it one undo step.55+func BenchmarkMacroReplay(b *testing.B) {56+ for _, relative := range []bool{false, true} {57+ name := "absolute"58+ if relative {59+ name = "relative"60+ }61+ src := macro.Source(recordingHeader(relative), replayActions(1000, relative))62+ b.Run(name+"/actions=1000", func(b *testing.B) {63+ b.ReportAllocs()64+ for b.Loop() {65+ b.StopTimer()66+ m := newModel()67+ m.book().SaveMacro("", sheet.Macro{Name: "Bench", Source: src}, "add")68+ m.trustHere()69+ mc, _ := m.book().Macro("Bench")70+ b.StartTimer()71+ run(m, m.runMacro(mc))72+ if m.warn != "" {73+ b.Fatal(m.warn)74+ }75+ }76+ b.ReportMetric(float64(b.Elapsed().Nanoseconds())/float64(b.N)/1000, "ns/action")77+ })78+ }79+}80+81+// BenchmarkMacroScript is a script's own loop: 10,000 cells set and read82+// back, to show what a call to the spreadsheet costs next to Starlark83+// computing on its own.84+func BenchmarkMacroScript(b *testing.B) {85+ src := "for i in range(1, 5001):\n set(\"A\" + str(i), i)\n x = get(\"A\" + str(i))\n"86+ b.ReportAllocs()87+ for b.Loop() {88+ b.StopTimer()89+ m := newModel()90+ m.book().SaveMacro("", sheet.Macro{Name: "Loop", Source: src}, "add")91+ m.trustHere()92+ mc, _ := m.book().Macro("Loop")93+ b.StartTimer()94+ run(m, m.runMacro(mc))95+ if m.warn != "" {96+ b.Fatal(m.warn)97+ }98+ }99+ b.ReportMetric(float64(b.Elapsed().Nanoseconds())/float64(b.N)/10000, "ns/call")100+}
M internal/ui/macrohost.go +6 -2