diff --git a/Makefile b/Makefile index f3c0ca0d..a0a1417a 100644 --- a/Makefile +++ b/Makefile @@ -79,7 +79,7 @@ bench-compare: for i in 1 2 3; do \ go test -bench=. ./internal/...; \ done > benchmark_results - benchstat benchmark_results_baseline benchmark_results + benchstat -alpha 0.15 benchmark_results_baseline benchmark_results clean: rm -f micro diff --git a/internal/util/unicode.go b/internal/util/unicode.go index f1bb9896..14243e68 100644 --- a/internal/util/unicode.go +++ b/internal/util/unicode.go @@ -16,6 +16,16 @@ import ( // For rendering, micro will display the combining characters. It's not perfect // but it's pretty good. +var minMark = rune(unicode.Mark.R16[0].Lo) + +func isMark(r rune) bool { + // Fast path + if r < minMark { + return false + } + return unicode.In(r, unicode.Mark) +} + // DecodeCharacter returns the next character from an array of bytes // A character is a rune along with any accompanying combining runes func DecodeCharacter(b []byte) (rune, []rune, int) { @@ -24,7 +34,7 @@ func DecodeCharacter(b []byte) (rune, []rune, int) { c, s := utf8.DecodeRune(b) var combc []rune - for unicode.In(c, unicode.Mark) { + for isMark(c) { combc = append(combc, c) size += s @@ -43,7 +53,7 @@ func DecodeCharacterInString(str string) (rune, []rune, int) { c, s := utf8.DecodeRuneInString(str) var combc []rune - for unicode.In(c, unicode.Mark) { + for isMark(c) { combc = append(combc, c) size += s @@ -61,7 +71,7 @@ func CharacterCount(b []byte) int { for len(b) > 0 { r, size := utf8.DecodeRune(b) - if !unicode.In(r, unicode.Mark) { + if !isMark(r) { s++ } @@ -77,7 +87,7 @@ func CharacterCountInString(str string) int { s := 0 for _, r := range str { - if !unicode.In(r, unicode.Mark) { + if !isMark(r) { s++ } } diff --git a/pkg/highlight/unicode.go b/pkg/highlight/unicode.go index 646c2eec..a18118a6 100644 --- a/pkg/highlight/unicode.go +++ b/pkg/highlight/unicode.go @@ -5,6 +5,16 @@ import ( "unicode/utf8" ) +var minMark = rune(unicode.Mark.R16[0].Lo) + +func isMark(r rune) bool { + // Fast path + if r < minMark { + return false + } + return unicode.In(r, unicode.Mark) +} + // DecodeCharacter returns the next character from an array of bytes // A character is a rune along with any accompanying combining runes func DecodeCharacter(b []byte) (rune, []rune, int) { @@ -13,7 +23,7 @@ func DecodeCharacter(b []byte) (rune, []rune, int) { c, s := utf8.DecodeRune(b) var combc []rune - for unicode.In(c, unicode.Mark) { + for isMark(c) { combc = append(combc, c) size += s @@ -32,7 +42,7 @@ func DecodeCharacterInString(str string) (rune, []rune, int) { c, s := utf8.DecodeRuneInString(str) var combc []rune - for unicode.In(c, unicode.Mark) { + for isMark(c) { combc = append(combc, c) size += s @@ -50,7 +60,7 @@ func CharacterCount(b []byte) int { for len(b) > 0 { r, size := utf8.DecodeRune(b) - if !unicode.In(r, unicode.Mark) { + if !isMark(r) { s++ } @@ -66,7 +76,7 @@ func CharacterCountInString(str string) int { s := 0 for _, r := range str { - if !unicode.In(r, unicode.Mark) { + if !isMark(r) { s++ } }