esimonov / ifshort

Go linter for checking that your code uses short syntax for if-statements whenever possible.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

ifshort is extreamly slow for larger builder patters

ThomasObenaus opened this issue · comments

Description of the problem

Context

I like to use the build pattern approach where function calls are 'just' concatenated without storing intermediate results to configure something and then generate the result.

Problem

In case enough calls are concatenated (~30) then the ifshort linter performance degrades drastically with each added call.

Example Code

package main

func main() {
	t := thing{}
	t.add().add().add().add().add().add().add().add().add().add().add().add().add().
		add().add().add().add().add().add().add().add().add().add().add().add().add()
}

type thing struct {
}

func (t thing) add() thing {
	return t
}

When I then call the linter

./ifshort  -debug vfpst  .

The run takes ~ 900ms but when I add more calls the performance degrades drastically:

  • 1 more add: 1.7s
  • 2 more add: 3.4s
  • 3 more add: 6.8s
  • 4 more add: 13.8s
  • 5 more add: 27.3s
  • 6 more add: 54.5s
  • 7 more add: 1.48m

We had a builder with enough calls that lead to a execution of ifshort time of > 20m resulting in our pipeline to timeout.
And it took a while to figure out what is the actual problem.

Version of ifshort

v1.0.4 (==master)

Go environment

go version go1.17.7 linux/amd64
GO111MODULE=""
GOARCH="amd64"
GOBIN=""
GOCACHE="/home/m/.cache/go-build"
GOENV="/home/m/.config/go/env"
GOEXE=""
GOEXPERIMENT=""
GOFLAGS=""
GOHOSTARCH="amd64"
GOHOSTOS="linux"
GOINSECURE=""
GOMODCACHE="/home/m/work/gocode/pkg/mod"
GONOPROXY=""
GONOSUMDB=""
GOOS="linux"
GOPATH="/home/m/work/gocode"
GOPRIVATE=""
GOPROXY="https://proxy.golang.org,direct"
GOROOT="/usr/local/go"
GOSUMDB="sum.golang.org"
GOTMPDIR=""
GOTOOLDIR="/usr/local/go/pkg/tool/linux_amd64"
GOVCS=""
GOVERSION="go1.17.7"
GCCGO="gccgo"
AR="ar"
CC="gcc"
CXX="g++"
CGO_ENABLED="1"
GOMOD="/home/m/work/n/ifshort-bug/go.mod"
CGO_CFLAGS="-g -O2"
CGO_CPPFLAGS=""
CGO_CXXFLAGS="-g -O2"
CGO_FFLAGS="-g -O2"
CGO_LDFLAGS="-g -O2"
PKG_CONFIG="pkg-config"
GOGCCFLAGS="-fPIC -m64 -pthread -fmessage-length=0 -fdebug-prefix-map=/tmp/go-build1585209923=/tmp/go-build -gno-record-gcc-switches"

Verbose output of running

10:12:40.122061 load [.]
10:12:40.193156 building graph of analysis passes
1m43.554850346s ifshort@ifshort-bug

Code example or link to a public repository

package main

func main() {
	t := thing{}
	t.add().add().add().add().add().add().add().add().add().add().add().add().add().
		add().add().add().add().add().add().add().add().add().add().add().add().add()
}

type thing struct {
}

func (t thing) add() thing {
	return t
}

Hi @esimonov,

did you had time to look into this performance issue?