mirror of
https://github.com/peco/peco.git
synced 2026-09-10 07:16:29 -04:00
fix: fast-path StripANSISequence to skip regexp when no ESC byte
Benchmark (10k lines): plain text: 1023us -> 37us (-96%), 1.7MiB -> 0B (-100%), 30k -> 0 allocs 95% plain: 1064us -> 162us (-85%), 1720KiB -> 63KiB (-96%), 30.5k -> 2k allocs
This commit is contained in:
parent
a79df901f7
commit
4b1dfa1c4d
40
internal/util/bench_test.go
Normal file
40
internal/util/bench_test.go
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
package util
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func BenchmarkStripANSISequenceBulk(b *testing.B) {
|
||||
b.Run("10k_plain_lines", func(b *testing.B) {
|
||||
lines := make([]string, 10_000)
|
||||
for i := range lines {
|
||||
lines[i] = fmt.Sprintf("line %d: this is a typical line without any ansi codes at all padding", i)
|
||||
}
|
||||
b.ResetTimer()
|
||||
b.ReportAllocs()
|
||||
for b.Loop() {
|
||||
for _, l := range lines {
|
||||
StripANSISequence(l)
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
b.Run("10k_mixed_95pct_plain", func(b *testing.B) {
|
||||
lines := make([]string, 10_000)
|
||||
for i := range lines {
|
||||
if i%20 == 0 {
|
||||
lines[i] = fmt.Sprintf("\x1b[31mline %d\x1b[0m: this has ansi codes in it for color", i)
|
||||
} else {
|
||||
lines[i] = fmt.Sprintf("line %d: this is a typical line without any ansi codes at all padding", i)
|
||||
}
|
||||
}
|
||||
b.ResetTimer()
|
||||
b.ReportAllocs()
|
||||
for b.Loop() {
|
||||
for _, l := range lines {
|
||||
StripANSISequence(l)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
|
@ -3,6 +3,7 @@ package util
|
|||
import (
|
||||
"errors"
|
||||
"regexp"
|
||||
"strings"
|
||||
"unicode"
|
||||
)
|
||||
|
||||
|
|
@ -44,8 +45,13 @@ func ContainsUpper(query string) bool {
|
|||
// Global var used to strips ansi sequences
|
||||
var reANSIEscapeChars = regexp.MustCompile("\x1B\\[(?:[0-9]{1,2}(?:;[0-9]{1,2})?)*[a-zA-Z]")
|
||||
|
||||
// StripANSISequence strips ANSI escape sequences from the given string
|
||||
// StripANSISequence strips ANSI escape sequences from the given string.
|
||||
// Fast-path: if the string contains no ESC byte, return it unchanged
|
||||
// to avoid a regexp allocation.
|
||||
func StripANSISequence(s string) string {
|
||||
if !strings.Contains(s, "\x1b") {
|
||||
return s
|
||||
}
|
||||
return reANSIEscapeChars.ReplaceAllString(s, "")
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue