test(perf): expand VT baseline coverage
- commit
- a667323e9602b9da58d4081c30da44bfae37898c
- author
- brice · · 2026-08-20 08:28 UTC
- parent
- 52147d7
- signature
- GPG Verified
CD88F9E564E0102646FB6077A1A07C7C7C3E349D· arch-gpg Verified for the committer email
1 file · +59 -0
M benchmark_test.go +59 -0
| @@ -10,6 +10,7 @@ import ( | |||
| 10 | 10 | var ( | |
| 11 | 11 | benchmarkHistoryViewSink HistoryView | |
| 12 | 12 | benchmarkHistorySnapshotSink HistorySnapshotView | |
| 13 | + | benchmarkDamageCaptureSink DamageCapture | |
| 13 | 14 | benchmarkHistoryBlobSink []byte | |
| 14 | 15 | benchmarkHistoryBlobsSink [][]byte | |
| 15 | 16 | ) | |
| @@ -200,6 +201,14 @@ func benchmarkScreenResizeReflow(b *testing.B, historyRows int) { | |||
| 200 | 201 | for range historyRows { | |
| 201 | 202 | requireHistoryAppend(b, s.history, make([]renderer.Cell, 120)) | |
| 202 | 203 | } | |
| 204 | + | // History normally receives rows evicted from this screen, whose IDs are | |
| 205 | + | // allocated after every existing live or historical row. This fixture | |
| 206 | + | // prepopulates history directly, so advance and refresh the live IDs to | |
| 207 | + | // preserve that invariant before exercising resize eviction. | |
| 208 | + | s.nextRowID = s.history.nextRowID - 1 | |
| 209 | + | for y := range s.buffer.rowIDs { | |
| 210 | + | s.buffer.rowIDs[y] = s.nextRowIDValue() | |
| 211 | + | } | |
| 203 | 212 | } | |
| 204 | 213 | s.Write(bytes.Repeat([]byte("x"), 120*39)) | |
| 205 | 214 | s.ClearDamage() | |
| @@ -217,6 +226,56 @@ func benchmarkScreenResizeReflow(b *testing.B, historyRows int) { | |||
| 217 | 226 | } | |
| 218 | 227 | } | |
| 219 | 228 | ||
| 229 | + | func BenchmarkScreenPrintableASCII(b *testing.B) { | |
| 230 | + | s := NewScreen(120, 40) | |
| 231 | + | chunk := append(bytes.Repeat([]byte("x"), 119), '\r') | |
| 232 | + | b.SetBytes(int64(len(chunk))) | |
| 233 | + | b.ReportAllocs() | |
| 234 | + | for b.Loop() { | |
| 235 | + | s.Write(chunk) | |
| 236 | + | s.ClearDamage() | |
| 237 | + | } | |
| 238 | + | } | |
| 239 | + | ||
| 240 | + | func BenchmarkScreenMixedUTF8(b *testing.B) { | |
| 241 | + | s := NewScreen(120, 40) | |
| 242 | + | chunk := append(bytes.Repeat([]byte("Aé界"), 20), '\r') | |
| 243 | + | b.SetBytes(int64(len(chunk))) | |
| 244 | + | b.ReportAllocs() | |
| 245 | + | for b.Loop() { | |
| 246 | + | s.Write(chunk) | |
| 247 | + | s.ClearDamage() | |
| 248 | + | } | |
| 249 | + | } | |
| 250 | + | ||
| 251 | + | func BenchmarkScreenCSIHeavy(b *testing.B) { | |
| 252 | + | s := NewScreen(120, 40) | |
| 253 | + | chunk := []byte("\x1b[1;1H\x1b[2K\x1b[31;48;2;1;2;3mstatus\x1b[0m\x1b[10C\x1b[?25l\x1b[?25h\r") | |
| 254 | + | b.SetBytes(int64(len(chunk))) | |
| 255 | + | b.ReportAllocs() | |
| 256 | + | for b.Loop() { | |
| 257 | + | s.Write(chunk) | |
| 258 | + | s.ClearDamage() | |
| 259 | + | } | |
| 260 | + | } | |
| 261 | + | ||
| 262 | + | func BenchmarkScreenCaptureDamage(b *testing.B) { | |
| 263 | + | s := NewScreen(120, 40) | |
| 264 | + | chunk := []byte("x") | |
| 265 | + | s.ClearDamage() | |
| 266 | + | b.ReportAllocs() | |
| 267 | + | for b.Loop() { | |
| 268 | + | s.Write(chunk) | |
| 269 | + | benchmarkDamageCaptureSink = s.CaptureDamage() | |
| 270 | + | if len(benchmarkDamageCaptureSink.Damage) == 0 { | |
| 271 | + | b.Fatal("expected captured damage") | |
| 272 | + | } | |
| 273 | + | if !s.AcknowledgeDamage(benchmarkDamageCaptureSink.Generation) { | |
| 274 | + | b.Fatal("expected current damage acknowledgement") | |
| 275 | + | } | |
| 276 | + | } | |
| 277 | + | } | |
| 278 | + | ||
| 220 | 279 | func BenchmarkScreenShellRedrawBurst(b *testing.B) { | |
| 221 | 280 | chunk := []byte("\r\x1b[K❯ abc\x1b[90m autosuggestion\x1b[39m\r\x1b[5C") | |
| 222 | 281 | b.ReportAllocs() | |
| @@ -10,6 +10,7 @@ import ( | |||||
| 10 | var ( | 10 | var ( | ||
| 11 | benchmarkHistoryViewSink HistoryView | 11 | benchmarkHistoryViewSink HistoryView | ||
| 12 | benchmarkHistorySnapshotSink HistorySnapshotView | 12 | benchmarkHistorySnapshotSink HistorySnapshotView | ||
| 13 | + | benchmarkDamageCaptureSink DamageCapture | |||
| 13 | benchmarkHistoryBlobSink []byte | 14 | benchmarkHistoryBlobSink []byte | ||
| 14 | benchmarkHistoryBlobsSink [][]byte | 15 | benchmarkHistoryBlobsSink [][]byte | ||
| 15 | ) | 16 | ) | ||
| @@ -200,6 +201,14 @@ func benchmarkScreenResizeReflow(b *testing.B, historyRows int) { | |||||
| 200 | for range historyRows { | 201 | for range historyRows { | ||
| 201 | requireHistoryAppend(b, s.history, make([]renderer.Cell, 120)) | 202 | requireHistoryAppend(b, s.history, make([]renderer.Cell, 120)) | ||
| 202 | } | 203 | } | ||
| 204 | + | // History normally receives rows evicted from this screen, whose IDs are | |||
| 205 | + | // allocated after every existing live or historical row. This fixture | |||
| 206 | + | // prepopulates history directly, so advance and refresh the live IDs to | |||
| 207 | + | // preserve that invariant before exercising resize eviction. | |||
| 208 | + | s.nextRowID = s.history.nextRowID - 1 | |||
| 209 | + | for y := range s.buffer.rowIDs { | |||
| 210 | + | s.buffer.rowIDs[y] = s.nextRowIDValue() | |||
| 211 | + | } | |||
| 203 | } | 212 | } | ||
| 204 | s.Write(bytes.Repeat([]byte("x"), 120*39)) | 213 | s.Write(bytes.Repeat([]byte("x"), 120*39)) | ||
| 205 | s.ClearDamage() | 214 | s.ClearDamage() | ||
| @@ -217,6 +226,56 @@ func benchmarkScreenResizeReflow(b *testing.B, historyRows int) { | |||||
| 217 | } | 226 | } | ||
| 218 | } | 227 | } | ||
| 219 | 228 | ||||
| 229 | + | func BenchmarkScreenPrintableASCII(b *testing.B) { | |||
| 230 | + | s := NewScreen(120, 40) | |||
| 231 | + | chunk := append(bytes.Repeat([]byte("x"), 119), '\r') | |||
| 232 | + | b.SetBytes(int64(len(chunk))) | |||
| 233 | + | b.ReportAllocs() | |||
| 234 | + | for b.Loop() { | |||
| 235 | + | s.Write(chunk) | |||
| 236 | + | s.ClearDamage() | |||
| 237 | + | } | |||
| 238 | + | } | |||
| 239 | + | ||||
| 240 | + | func BenchmarkScreenMixedUTF8(b *testing.B) { | |||
| 241 | + | s := NewScreen(120, 40) | |||
| 242 | + | chunk := append(bytes.Repeat([]byte("Aé界"), 20), '\r') | |||
| 243 | + | b.SetBytes(int64(len(chunk))) | |||
| 244 | + | b.ReportAllocs() | |||
| 245 | + | for b.Loop() { | |||
| 246 | + | s.Write(chunk) | |||
| 247 | + | s.ClearDamage() | |||
| 248 | + | } | |||
| 249 | + | } | |||
| 250 | + | ||||
| 251 | + | func BenchmarkScreenCSIHeavy(b *testing.B) { | |||
| 252 | + | s := NewScreen(120, 40) | |||
| 253 | + | chunk := []byte("\x1b[1;1H\x1b[2K\x1b[31;48;2;1;2;3mstatus\x1b[0m\x1b[10C\x1b[?25l\x1b[?25h\r") | |||
| 254 | + | b.SetBytes(int64(len(chunk))) | |||
| 255 | + | b.ReportAllocs() | |||
| 256 | + | for b.Loop() { | |||
| 257 | + | s.Write(chunk) | |||
| 258 | + | s.ClearDamage() | |||
| 259 | + | } | |||
| 260 | + | } | |||
| 261 | + | ||||
| 262 | + | func BenchmarkScreenCaptureDamage(b *testing.B) { | |||
| 263 | + | s := NewScreen(120, 40) | |||
| 264 | + | chunk := []byte("x") | |||
| 265 | + | s.ClearDamage() | |||
| 266 | + | b.ReportAllocs() | |||
| 267 | + | for b.Loop() { | |||
| 268 | + | s.Write(chunk) | |||
| 269 | + | benchmarkDamageCaptureSink = s.CaptureDamage() | |||
| 270 | + | if len(benchmarkDamageCaptureSink.Damage) == 0 { | |||
| 271 | + | b.Fatal("expected captured damage") | |||
| 272 | + | } | |||
| 273 | + | if !s.AcknowledgeDamage(benchmarkDamageCaptureSink.Generation) { | |||
| 274 | + | b.Fatal("expected current damage acknowledgement") | |||
| 275 | + | } | |||
| 276 | + | } | |||
| 277 | + | } | |||
| 278 | + | ||||
| 220 | func BenchmarkScreenShellRedrawBurst(b *testing.B) { | 279 | func BenchmarkScreenShellRedrawBurst(b *testing.B) { | ||
| 221 | chunk := []byte("\r\x1b[K❯ abc\x1b[90m autosuggestion\x1b[39m\r\x1b[5C") | 280 | chunk := []byte("\r\x1b[K❯ abc\x1b[90m autosuggestion\x1b[39m\r\x1b[5C") | ||
| 222 | b.ReportAllocs() | 281 | b.ReportAllocs() | ||