Skip to content

Commit

Permalink
perf(ansistyles): Improve performance of hex color parsing.
Browse files Browse the repository at this point in the history
  • Loading branch information
jwalton committed Oct 12, 2021
1 parent 06ee648 commit 8c71ae9
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 6 deletions.
7 changes: 7 additions & 0 deletions pkg/ansistyles/ansistyle_benchmark_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,3 +28,10 @@ func BenchmarkWriteStringAnsi(b *testing.B) {
WriteStringAnsi(&out, 7)
}
}

func BenchmarkParsingHex(b *testing.B) {
b.ReportAllocs()
for i := 0; i < b.N; i++ {
HexToRGB("#8000ff")
}
}
32 changes: 26 additions & 6 deletions pkg/ansistyles/ansistyles.go
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,6 @@ package ansistyles
import (
"fmt"
"math"
"regexp"
"strings"
)

Expand Down Expand Up @@ -486,7 +485,30 @@ func RGBToAnsi256(red uint8, green uint8, blue uint8) uint8 {
math.Round(float64(blue)/255*5))
}

var hexColorRegex = regexp.MustCompile(`([a-fA-F\d]{6}|[a-fA-F\d]{3})`)
func isHexDigit(c byte) bool {
return c >= '0' && c <= '9' || c >= 'a' && c <= 'f' || c >= 'A' && c <= 'F'
}

func parseHexColor(str string) string {
index := 0

// Find the "#"
if index < len(str) && str[index] == '#' {
index++
}

hexStart := index
for index < len(str) && isHexDigit(str[index]) {
index++
}

colorStr := str[hexStart:index]
if len(colorStr) != 3 && len(colorStr) != 6 {
return ""
}

return colorStr
}

// HexToRGB converts from the RGB HEX color space to the RGB color space.
//
Expand All @@ -495,13 +517,11 @@ var hexColorRegex = regexp.MustCompile(`([a-fA-F\d]{6}|[a-fA-F\d]{3})`)
// this will return 0, 0, 0 - it's up to you to validate the input if you want to
// detect invalid values.
func HexToRGB(hex string) (red uint8, green uint8, blue uint8) {
matches := hexColorRegex.FindStringSubmatch(hex)
if matches == nil {
s := parseHexColor(hex)
if s == "" {
return 0, 0, 0
}

s := matches[0]

// Adapted from https://stackoverflow.com/questions/54197913/parse-hex-string-to-image-color
hexToByte := func(b byte) byte {
switch {
Expand Down

0 comments on commit 8c71ae9

Please sign in to comment.