test(daemon): remove timed fixture allocations
- commit
- 2a2a3fb601fc8c36c839c31de1949cb43baf98d4
- author
- brice · · 2026-07-11 05:00 UTC
- committer
- brice · · 2026-07-11 06:15 UTC
- parent
- 0ba01b1
- signature
- GPG Verified
CD88F9E564E0102646FB6077A1A07C7C7C3E349D· arch-gpg Verified for the committer email
1 file · +30 -9
M internal/usecase/daemon/performance_benchmark_test.go +30 -9
| @@ -36,6 +36,21 @@ func TestPerformanceFixtureCounters(t *testing.T) { | |||
| 36 | 36 | require.True(t, fixture.resized()) | |
| 37 | 37 | } | |
| 38 | 38 | ||
| 39 | + | func TestPerformanceFixturePaintLiveUsesPrecomputedAlternatingWrites(t *testing.T) { | |
| 40 | + | fixture := newPerformanceFixture(t, performanceConfig{}) | |
| 41 | + | ||
| 42 | + | require.NotNil(t, fixture.activePane) | |
| 43 | + | require.Equal(t, [][]byte{ | |
| 44 | + | []byte("\x1b[1;1HA\x1b[2;2HA"), | |
| 45 | + | []byte("\x1b[1;1HB\x1b[2;2HB"), | |
| 46 | + | }, fixture.liveWrites) | |
| 47 | + | ||
| 48 | + | for range 4 { | |
| 49 | + | fixture.paintLive() | |
| 50 | + | } | |
| 51 | + | require.Equal(t, uint64(4), fixture.metrics().outputFrames) | |
| 52 | + | } | |
| 53 | + | ||
| 39 | 54 | // performanceConfig intentionally describes only an in-process daemon shape: | |
| 40 | 55 | // no PTY readers, schedulers, clocks, or transports are started by this fixture. | |
| 41 | 56 | type performanceConfig struct { | |
| @@ -57,6 +72,8 @@ type performanceFixture struct { | |||
| 57 | 72 | ac *attachedClient | |
| 58 | 73 | output *countingOutputTransport | |
| 59 | 74 | snaps *countingSnapshotStore | |
| 75 | + | activePane *pane | |
| 76 | + | liveWrites [][]byte | |
| 60 | 77 | paints int | |
| 61 | 78 | resizedSize domain.Size | |
| 62 | 79 | } | |
| @@ -74,11 +91,20 @@ func newPerformanceFixture(t testing.TB, config performanceConfig) *performanceF | |||
| 74 | 91 | sess.ephemeral = false | |
| 75 | 92 | sess.snapEligible.Store(true) | |
| 76 | 93 | ||
| 77 | - | fixture := &performanceFixture{t: t, d: d, sess: sess, ac: ac, output: output, snaps: &countingSnapshotStore{}} | |
| 94 | + | fixture := &performanceFixture{ | |
| 95 | + | t: t, | |
| 96 | + | d: d, | |
| 97 | + | sess: sess, | |
| 98 | + | ac: ac, | |
| 99 | + | output: output, | |
| 100 | + | snaps: &countingSnapshotStore{}, | |
| 101 | + | liveWrites: [][]byte{[]byte("\x1b[1;1HA\x1b[2;2HA"), []byte("\x1b[1;1HB\x1b[2;2HB")}, | |
| 102 | + | } | |
| 78 | 103 | WithSnapshotStore(fixture.snaps)(d) | |
| 79 | 104 | for tabIndex, tb := range sess.tabs { | |
| 80 | 105 | fixture.configureTab(tb, tabIndex, tabSize(config.size)) | |
| 81 | 106 | } | |
| 107 | + | fixture.activePane = fixture.findActivePane() | |
| 82 | 108 | ||
| 83 | 109 | // Prime the real renderer shadow before measurements. Subsequent paints use | |
| 84 | 110 | // actual production diffs rather than the initial full frame. | |
| @@ -123,7 +149,7 @@ func performanceFullWidthRow(width, tabIndex, row int) string { | |||
| 123 | 149 | return string(out) | |
| 124 | 150 | } | |
| 125 | 151 | ||
| 126 | - | func (f *performanceFixture) activePane() *pane { | |
| 152 | + | func (f *performanceFixture) findActivePane() *pane { | |
| 127 | 153 | f.t.Helper() | |
| 128 | 154 | tb := f.sess.activeTab() | |
| 129 | 155 | require.NotNil(f.t, tb) | |
| @@ -133,14 +159,9 @@ func (f *performanceFixture) activePane() *pane { | |||
| 133 | 159 | } | |
| 134 | 160 | ||
| 135 | 161 | func (f *performanceFixture) paintLive() { | |
| 136 | - | f.t.Helper() | |
| 137 | - | p := f.activePane() | |
| 138 | - | x, y := 1, 1 | |
| 139 | - | if f.paints%2 == 1 { | |
| 140 | - | x, y = 2, 2 | |
| 141 | - | } | |
| 162 | + | p := f.activePane | |
| 142 | 163 | p.mu.Lock() | |
| 143 | - | p.screen.Write([]byte(fmt.Sprintf("\x1b[%d;%dH%c", y, x, 'A'+rune(f.paints)))) | |
| 164 | + | p.screen.Write(f.liveWrites[f.paints%len(f.liveWrites)]) | |
| 144 | 165 | p.mu.Unlock() | |
| 145 | 166 | f.d.paint(f.sess, f.ac, false) | |
| 146 | 167 | f.paints++ | |
| @@ -36,6 +36,21 @@ func TestPerformanceFixtureCounters(t *testing.T) { | |||||
| 36 | require.True(t, fixture.resized()) | 36 | require.True(t, fixture.resized()) | ||
| 37 | } | 37 | } | ||
| 38 | 38 | ||||
| 39 | + | func TestPerformanceFixturePaintLiveUsesPrecomputedAlternatingWrites(t *testing.T) { | |||
| 40 | + | fixture := newPerformanceFixture(t, performanceConfig{}) | |||
| 41 | + | ||||
| 42 | + | require.NotNil(t, fixture.activePane) | |||
| 43 | + | require.Equal(t, [][]byte{ | |||
| 44 | + | []byte("\x1b[1;1HA\x1b[2;2HA"), | |||
| 45 | + | []byte("\x1b[1;1HB\x1b[2;2HB"), | |||
| 46 | + | }, fixture.liveWrites) | |||
| 47 | + | ||||
| 48 | + | for range 4 { | |||
| 49 | + | fixture.paintLive() | |||
| 50 | + | } | |||
| 51 | + | require.Equal(t, uint64(4), fixture.metrics().outputFrames) | |||
| 52 | + | } | |||
| 53 | + | ||||
| 39 | // performanceConfig intentionally describes only an in-process daemon shape: | 54 | // performanceConfig intentionally describes only an in-process daemon shape: | ||
| 40 | // no PTY readers, schedulers, clocks, or transports are started by this fixture. | 55 | // no PTY readers, schedulers, clocks, or transports are started by this fixture. | ||
| 41 | type performanceConfig struct { | 56 | type performanceConfig struct { | ||
| @@ -57,6 +72,8 @@ type performanceFixture struct { | |||||
| 57 | ac *attachedClient | 72 | ac *attachedClient | ||
| 58 | output *countingOutputTransport | 73 | output *countingOutputTransport | ||
| 59 | snaps *countingSnapshotStore | 74 | snaps *countingSnapshotStore | ||
| 75 | + | activePane *pane | |||
| 76 | + | liveWrites [][]byte | |||
| 60 | paints int | 77 | paints int | ||
| 61 | resizedSize domain.Size | 78 | resizedSize domain.Size | ||
| 62 | } | 79 | } | ||
| @@ -74,11 +91,20 @@ func newPerformanceFixture(t testing.TB, config performanceConfig) *performanceF | |||||
| 74 | sess.ephemeral = false | 91 | sess.ephemeral = false | ||
| 75 | sess.snapEligible.Store(true) | 92 | sess.snapEligible.Store(true) | ||
| 76 | 93 | ||||
| 77 | - | fixture := &performanceFixture{t: t, d: d, sess: sess, ac: ac, output: output, snaps: &countingSnapshotStore{}} | 94 | + | fixture := &performanceFixture{ |
| 95 | + | t: t, | |||
| 96 | + | d: d, | |||
| 97 | + | sess: sess, | |||
| 98 | + | ac: ac, | |||
| 99 | + | output: output, | |||
| 100 | + | snaps: &countingSnapshotStore{}, | |||
| 101 | + | liveWrites: [][]byte{[]byte("\x1b[1;1HA\x1b[2;2HA"), []byte("\x1b[1;1HB\x1b[2;2HB")}, | |||
| 102 | + | } | |||
| 78 | WithSnapshotStore(fixture.snaps)(d) | 103 | WithSnapshotStore(fixture.snaps)(d) | ||
| 79 | for tabIndex, tb := range sess.tabs { | 104 | for tabIndex, tb := range sess.tabs { | ||
| 80 | fixture.configureTab(tb, tabIndex, tabSize(config.size)) | 105 | fixture.configureTab(tb, tabIndex, tabSize(config.size)) | ||
| 81 | } | 106 | } | ||
| 107 | + | fixture.activePane = fixture.findActivePane() | |||
| 82 | 108 | ||||
| 83 | // Prime the real renderer shadow before measurements. Subsequent paints use | 109 | // Prime the real renderer shadow before measurements. Subsequent paints use | ||
| 84 | // actual production diffs rather than the initial full frame. | 110 | // actual production diffs rather than the initial full frame. | ||
| @@ -123,7 +149,7 @@ func performanceFullWidthRow(width, tabIndex, row int) string { | |||||
| 123 | return string(out) | 149 | return string(out) | ||
| 124 | } | 150 | } | ||
| 125 | 151 | ||||
| 126 | - | func (f *performanceFixture) activePane() *pane { | 152 | + | func (f *performanceFixture) findActivePane() *pane { |
| 127 | f.t.Helper() | 153 | f.t.Helper() | ||
| 128 | tb := f.sess.activeTab() | 154 | tb := f.sess.activeTab() | ||
| 129 | require.NotNil(f.t, tb) | 155 | require.NotNil(f.t, tb) | ||
| @@ -133,14 +159,9 @@ func (f *performanceFixture) activePane() *pane { | |||||
| 133 | } | 159 | } | ||
| 134 | 160 | ||||
| 135 | func (f *performanceFixture) paintLive() { | 161 | func (f *performanceFixture) paintLive() { | ||
| 136 | - | f.t.Helper() | 162 | + | p := f.activePane |
| 137 | - | p := f.activePane() | |||
| 138 | - | x, y := 1, 1 | |||
| 139 | - | if f.paints%2 == 1 { | |||
| 140 | - | x, y = 2, 2 | |||
| 141 | - | } | |||
| 142 | p.mu.Lock() | 163 | p.mu.Lock() | ||
| 143 | - | p.screen.Write([]byte(fmt.Sprintf("\x1b[%d;%dH%c", y, x, 'A'+rune(f.paints)))) | 164 | + | p.screen.Write(f.liveWrites[f.paints%len(f.liveWrites)]) |
| 144 | p.mu.Unlock() | 165 | p.mu.Unlock() | ||
| 145 | f.d.paint(f.sess, f.ac, false) | 166 | f.d.paint(f.sess, f.ac, false) | ||
| 146 | f.paints++ | 167 | f.paints++ | ||