diff --git a/docs/src/config/sidebar.yml b/docs/src/config/sidebar.yml index 5b9bece29dd5..10608d3d8495 100644 --- a/docs/src/config/sidebar.yml +++ b/docs/src/config/sidebar.yml @@ -26,8 +26,6 @@ link: "/product/roadmap/" - label: "Trusted By" link: "/product/trusted-by/" - - label: "Comparison" - link: "/product/comparison/" - label: "GitHub" link: "https://github.com/golangci/golangci-lint" - label: Contributing diff --git a/docs/src/docs/product/comparison.mdx b/docs/src/docs/product/comparison.mdx deleted file mode 100644 index 216435514263..000000000000 --- a/docs/src/docs/product/comparison.mdx +++ /dev/null @@ -1,78 +0,0 @@ ---- -title: Comparison ---- - -## `golangci-lint` vs `gometalinter` - -GolangCI-Lint was created to fix the following issues with `gometalinter`: - -1. Slow work: `gometalinter` usually works for minutes in average projects. - **GolangCI-Lint works [2-7x times faster](/usage/performance)** by reusing work. -2. Huge memory consumption: parallel linters don't share the same program representation and can consume - `n` times more memory (`n` - concurrency). GolangCI-Lint fixes it by sharing representation and **consumes 26% less memory**. -3. Doesn't use real bounded concurrency: if you set it to `n` it can take up to `n*n` threads because of - forced threads in specific linters. `gometalinter` can't do anything about it because it runs linters as - black boxes in forked processes. In GolangCI-Lint we run all linters in one process and completely control - them. Configured concurrency will be correctly bounded. - This issue is important because you often want to set concurrency to the CPUs count minus one to - ensure you **do not freeze your PC** and be able to work on it while analyzing code. -4. Lack of nice output. We like how the `gcc` and `clang` compilers format their warnings: **using colors, - printing warning lines and showing the position in line**. -5. Too many issues. GolangCI-Lint cuts a lot of issues by using default exclude list of common false-positives. - By default, it has enabled **smart issues processing**: merge multiple issues for one line, merge issues with the - same text or from the same linter. All of these smart processors can be configured by the user. -6. Integration into large codebases. A good way to start using linters in a large project is not to fix a plethora - of existing issues, but to set up CI and **fix only issues in new commits**. You can use `revgrep` for it, but it's - yet another utility to install and configure. With `golangci-lint` it's much easier: `revgrep` is already built into - `golangci-lint` and you can use it with one option (`-n, --new` or `--new-from-rev`). -7. Installation. With `gometalinter`, you need to run a linters installation step. It's easy to forget this step and - end up with stale linters. It also complicates CI setup. GolangCI-Lint requires **no installation of linters**. -8. **Yaml or toml config**. Gometalinter's JSON isn't convenient for config files. - -## `golangci-lint` vs Running Linters Manually - -1. It will be much slower because `golangci-lint` runs all linters in parallel and shares 50-80% of linters work. -2. It will have less control and more false-positives: some linters can't be properly configured without hacks. -3. It will take more time because of different usages and need of tracking of versions of `n` linters. - -## Performance - -Benchmarks were executed on MacBook Pro (Retina, 13-inch, Late 2013), 2,4 GHz Intel Core i5, 8 GB 1600 MHz DDR3. -It has 4 cores and concurrent linting as a default consuming all cores. -Benchmark was run (and measured) automatically, see the code -[here](https://github.com/golangci/golangci-lint/blob/master/test/bench/bench_test.go) (`BenchmarkWithGometalinter`). - -We measure peak memory usage (RSS) by tracking of processes RSS every 5 ms. - -### Comparison with gometalinter - -We compare golangci-lint and gometalinter in default mode, but explicitly enable all linters because of small differences in the default configuration. - -```sh -$ golangci-lint run --no-config --issues-exit-code=0 --timeout=30m \ - --disable-all --enable=deadcode --enable=gocyclo --enable=golint --enable=varcheck \ - --enable=structcheck --enable=maligned --enable=errcheck --enable=dupl --enable=ineffassign \ - --enable=interfacer --enable=unconvert --enable=goconst --enable=gosec --enable=megacheck -$ gometalinter --deadline=30m --vendor --cyclo-over=30 --dupl-threshold=150 \ - --exclude= --skip=testdata --skip=builtin \ - --disable-all --enable=deadcode --enable=gocyclo --enable=golint --enable=varcheck \ - --enable=structcheck --enable=maligned --enable=errcheck --enable=dupl --enable=ineffassign \ - --enable=interfacer --enable=unconvert --enable=goconst --enable=gosec --enable=megacheck - ./... -``` - -| Repository | GolangCI Time | GolangCI Is Faster than Gometalinter | GolangCI Memory | GolangCI eats less memory than Gometalinter | -| ------------------------------------ | ------------- | ------------------------------------ | --------------- | ------------------------------------------- | -| gometalinter repo, 4 kLoC | 6s | **6.4x** | 0.7GB | 33% | -| self-repo, 4 kLoC | 12s | **7.5x** | 1.2GB | 41% | -| beego, 50 kLoC | 10s | **4.2x** | 1.4GB | 9% | -| hugo, 70 kLoC | 15s | **6.1x** | 1.6GB | 44% | -| consul, 127 kLoC | 58s | **4x** | 2.7GB | 41% | -| terraform, 190 kLoC | 2m13s | **1.6x** | 4.8GB | 0% | -| go-ethereum, 250 kLoC | 33s | **5x** | 3.6GB | 0% | -| go source (`$GOROOT/src`), 1300 kLoC | 2m45s | **2x** | 4.7GB | 0% | - -**On average golangci-lint is 4.6 times faster** than gometalinter. Maximum difference is in the -self-repo: **7.5 times faster**, minimum difference is in terraform source code repo: 1.8 times faster. - -On average golangci-lint consumes 26% less memory. diff --git a/docs/src/docs/usage/performance.mdx b/docs/src/docs/usage/performance.mdx index 0c8ddc16a706..06e6b5c73cbb 100644 --- a/docs/src/docs/usage/performance.mdx +++ b/docs/src/docs/usage/performance.mdx @@ -21,8 +21,9 @@ Less `GOGC` values trigger garbage collection more frequently and golangci-lint ## Why `golangci-lint` is so fast 1. Work sharing - The key difference with gometalinter is that golangci-lint shares work between specific linters (golint, govet, ...). - We don't fork to call specific linter but use its API. + + During operation, `golangci-lint` shares work between specific linters (like `golint`, `govet`, etc.). + We don't fork to call a specific linter, but instead use its API. For small and medium projects 50-90% of work between linters can be reused. - load `[]*packages.Package` by `go/packages` once