Skip to content
/ mirror Public

Use right mirror functions for string/[]byte performance bust

License

Notifications You must be signed in to change notification settings

butuzov/mirror

Folders and files

NameName
Last commit message
Last commit date

Latest commit

70b1ff9 · Nov 29, 2024

History

68 Commits
Nov 21, 2024
Nov 29, 2024
Jul 26, 2024
Nov 29, 2024
Sep 18, 2021
May 27, 2023
Mar 31, 2024
May 8, 2023
Nov 29, 2024
Nov 29, 2024
Dec 8, 2023
Nov 29, 2024
May 8, 2023
Dec 8, 2023
Dec 8, 2023
Dec 8, 2023
Nov 29, 2024
Dec 8, 2023
Dec 8, 2023
Dec 8, 2023
Dec 8, 2023
Jul 6, 2024
Jul 6, 2024
Nov 18, 2024

Repository files navigation

mirror Stand with Ukraine Code Coverage build status

mirror suggests use of alternative functions/methods in order to gain performance boosts by avoiding unnecessary []byte/string conversion calls. See MIRROR_FUNCS.md list of mirror functions you can use in go's stdlib.


United 24 Help Oleg Butuzov


Linter Use Cases

github.com/argoproj/argo-cd

// Before
func IsValidHostname(hostname string, fqdn bool) bool {
  if !fqdn {
    return validHostNameRegexp.Match([]byte(hostname)) || validIPv6Regexp.Match([]byte(hostname))
  } else {
    return validFQDNRegexp.Match([]byte(hostname))
  }
}

// After: With alternative method (and lost `else` case)
func IsValidHostname(hostname string, fqdn bool) bool {
  if !fqdn {
    return validHostNameRegexp.MatchString(hostname) || validIPv6Regexp.MatchString(hostname)
  }

  return validFQDNRegexp.MatchString(hostname)
}

Install

go install github.com/butuzov/mirror/cmd/mirror@latest

golangci-lint

golangci-lint supports mirror since v1.53.0

How to use

You run mirror with go vet:

go vet -vettool=$(which mirror) ./...
# github.com/jcmoraisjr/haproxy-ingress/pkg/common/net/ssl
pkg/common/net/ssl/ssl.go:64:11: avoid allocations with (*os.File).WriteString
pkg/common/net/ssl/ssl.go:161:12: avoid allocations with (*os.File).WriteString
pkg/common/net/ssl/ssl.go:166:3: avoid allocations with (*os.File).WriteString

Can be called directly:

mirror ./...
# https://github.com/cosmtrek/air
/air/runner/util.go:149:6: avoid allocations with (*regexp.Regexp).MatchString
/air/runner/util.go:173:14: avoid allocations with (*os.File).WriteString

With golangci-lint

golangci-lint run --no-config --disable-all -Emirror
# github.com/argoproj/argo-cd
test/e2e/fixture/app/actions.go:83:11: avoid allocations with (*os.File).WriteString (mirror)
	_, err = tmpFile.Write([]byte(data))
	         ^
server/server.go:1166:9: avoid allocations with (*regexp.Regexp).MatchString (mirror)
	return mainJsBundleRegex.Match([]byte(filename))
	       ^
server/account/account.go:91:6: avoid allocations with (*regexp.Regexp).MatchString (mirror)
	if !validPasswordRegexp.Match([]byte(q.NewPassword)) {
	    ^
server/badge/badge.go:52:20: avoid allocations with (*regexp.Regexp).FindAllStringSubmatchIndex (mirror)
	for _, v := range re.FindAllSubmatchIndex([]byte(str), -1) {
	                  ^
util/cert/cert.go:82:10: avoid allocations with (*regexp.Regexp).MatchString (mirror)
		return validHostNameRegexp.Match([]byte(hostname)) || validIPv6Regexp.Match([]byte(hostname))

Command line

  • You can add checks for _test.go files with cli option --with-tests

golangci-lint

With golangci-lint tests are checked by default and can be can be turned off by using the regular golangci-lint ways to do it:

  • flag --tests (e.g. --tests=false)
  • flag --skip-files (e.g. --skip-files="_test.go")
  • yaml configuration run.skip-files:
    run:
      skip-files:
        - '(.+)_test\.go'
  • yaml configuration issues.exclude-rules:
      issues:
        exclude-rules:
          - path: '(.+)_test\.go'
            linters:
              - mirror

Contributing

# Update Assets (testdata/(strings|bytes|os|utf8|maphash|regexp|bufio).go)
(task|make) generate
# Run Tests
(task|make) tests
# Lint Code
(task|make) lints