Skip to content

Commit 605cd76

Browse files
committed
Improve Color.Equals performance from O(n²) to O(n)
1 parent 4c05561 commit 605cd76

File tree

1 file changed

+20
-23
lines changed

1 file changed

+20
-23
lines changed

color.go

Lines changed: 20 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ var (
2020
// colors. For more control over each color block use the methods
2121
// DisableColor() individually.
2222
NoColor = noColorIsSet() || os.Getenv("TERM") == "dumb" ||
23-
(!isatty.IsTerminal(os.Stdout.Fd()) && !isatty.IsCygwinTerminal(os.Stdout.Fd()))
23+
(!isatty.IsTerminal(os.Stdout.Fd()) && !isatty.IsCygwinTerminal(os.Stdout.Fd()))
2424

2525
// Output defines the standard output of the print functions. By default,
2626
// os.Stdout is used.
@@ -404,11 +404,11 @@ func (c *Color) SprintlnFunc() func(a ...interface{}) string {
404404
// an example output might be: "1;36" -> bold cyan
405405
func (c *Color) sequence() string {
406406
format := make([]string, len(c.params))
407-
for i, v := range c.params {
408-
format[i] = strconv.Itoa(int(v))
409-
}
407+
for i, v := range c.params {
408+
format[i] = strconv.Itoa(int(v))
409+
}
410410

411-
return strings.Join(format, ";")
411+
return strings.Join(format, ";")
412412
}
413413

414414
// wrap wraps the s string with the colors attributes. The string is ready to
@@ -429,15 +429,15 @@ func (c *Color) unformat() string {
429429
//return fmt.Sprintf("%s[%dm", escape, Reset)
430430
//for each element in sequence let's use the specific reset escape, or the generic one if not found
431431
format := make([]string, len(c.params))
432-
for i, v := range c.params {
433-
format[i] = strconv.Itoa(int(Reset))
434-
ra, ok := mapResetAttributes[v]
435-
if ok {
436-
format[i] = strconv.Itoa(int(ra))
432+
for i, v := range c.params {
433+
format[i] = strconv.Itoa(int(Reset))
434+
ra, ok := mapResetAttributes[v]
435+
if ok {
436+
format[i] = strconv.Itoa(int(ra))
437+
}
437438
}
438-
}
439439

440-
return fmt.Sprintf("%s[%sm", escape, strings.Join(format, ";"))
440+
return fmt.Sprintf("%s[%sm", escape, strings.Join(format, ";"))
441441
}
442442

443443
// DisableColor disables the color output. Useful to not change any existing
@@ -471,27 +471,24 @@ func (c *Color) Equals(c2 *Color) bool {
471471
if c == nil || c2 == nil {
472472
return false
473473
}
474+
474475
if len(c.params) != len(c2.params) {
475476
return false
476477
}
477478

479+
counts := make(map[Attribute]int, len(c.params))
478480
for _, attr := range c.params {
479-
if !c2.attrExists(attr) {
480-
return false
481-
}
481+
counts[attr]++
482482
}
483483

484-
return true
485-
}
486-
487-
func (c *Color) attrExists(a Attribute) bool {
488-
for _, attr := range c.params {
489-
if attr == a {
490-
return true
484+
for _, attr := range c2.params {
485+
if counts[attr] == 0 {
486+
return false
491487
}
488+
counts[attr]--
492489
}
493490

494-
return false
491+
return true
495492
}
496493

497494
func boolPtr(v bool) *bool {

0 commit comments

Comments
 (0)