From 65330f8f0c52a4747ed40cef8a502ab054b836c9 Mon Sep 17 00:00:00 2001 From: golangci Date: Tue, 22 May 2018 22:43:47 +0300 Subject: [PATCH] improve benchmark --- Gopkg.lock | 20 +- Gopkg.toml | 4 + README.md | 50 +- pkg/enabled_linters_test.go | 159 +- vendor/github.com/mitchellh/go-ps/.gitignore | 1 + vendor/github.com/mitchellh/go-ps/.travis.yml | 4 + vendor/github.com/mitchellh/go-ps/LICENSE.md | 21 + vendor/github.com/mitchellh/go-ps/README.md | 34 + vendor/github.com/mitchellh/go-ps/Vagrantfile | 43 + vendor/github.com/mitchellh/go-ps/process.go | 40 + .../mitchellh/go-ps/process_darwin.go | 138 + .../mitchellh/go-ps/process_freebsd.go | 260 ++ .../mitchellh/go-ps/process_linux.go | 35 + .../mitchellh/go-ps/process_solaris.go | 96 + .../mitchellh/go-ps/process_unix.go | 101 + .../mitchellh/go-ps/process_windows.go | 119 + vendor/github.com/shirou/gopsutil/cpu/cpu.go | 189 ++ .../shirou/gopsutil/cpu/cpu_darwin.go | 115 + .../shirou/gopsutil/cpu/cpu_darwin_cgo.go | 111 + .../shirou/gopsutil/cpu/cpu_darwin_nocgo.go | 14 + .../shirou/gopsutil/cpu/cpu_fallback.go | 25 + .../shirou/gopsutil/cpu/cpu_freebsd.go | 168 ++ .../shirou/gopsutil/cpu/cpu_freebsd_386.go | 9 + .../shirou/gopsutil/cpu/cpu_freebsd_amd64.go | 9 + .../shirou/gopsutil/cpu/cpu_linux.go | 285 ++ .../shirou/gopsutil/cpu/cpu_openbsd.go | 119 + .../shirou/gopsutil/cpu/cpu_solaris.go | 198 ++ .../shirou/gopsutil/cpu/cpu_windows.go | 172 ++ .../github.com/shirou/gopsutil/host/host.go | 53 + .../shirou/gopsutil/host/host_darwin.go | 227 ++ .../shirou/gopsutil/host/host_darwin_386.go | 19 + .../shirou/gopsutil/host/host_darwin_amd64.go | 19 + .../shirou/gopsutil/host/host_fallback.go | 65 + .../shirou/gopsutil/host/host_freebsd.go | 245 ++ .../shirou/gopsutil/host/host_freebsd_386.go | 43 + .../gopsutil/host/host_freebsd_amd64.go | 44 + .../shirou/gopsutil/host/host_freebsd_arm.go | 44 + .../shirou/gopsutil/host/host_linux.go | 657 ++++ .../shirou/gopsutil/host/host_linux_386.go | 45 + .../shirou/gopsutil/host/host_linux_amd64.go | 48 + .../shirou/gopsutil/host/host_linux_arm.go | 43 + .../shirou/gopsutil/host/host_linux_arm64.go | 43 + .../shirou/gopsutil/host/host_linux_mips.go | 43 + .../shirou/gopsutil/host/host_linux_mips64.go | 43 + .../gopsutil/host/host_linux_mips64le.go | 43 + .../shirou/gopsutil/host/host_linux_mipsle.go | 43 + .../gopsutil/host/host_linux_ppc64le.go | 45 + .../shirou/gopsutil/host/host_linux_s390x.go | 45 + .../shirou/gopsutil/host/host_openbsd.go | 195 ++ .../gopsutil/host/host_openbsd_amd64.go | 31 + .../shirou/gopsutil/host/host_solaris.go | 248 ++ .../shirou/gopsutil/host/host_windows.go | 236 ++ .../shirou/gopsutil/host/types_darwin.go | 17 + .../shirou/gopsutil/host/types_freebsd.go | 44 + .../shirou/gopsutil/host/types_linux.go | 42 + .../shirou/gopsutil/host/types_openbsd.go | 43 + vendor/github.com/shirou/gopsutil/net/net.go | 248 ++ .../shirou/gopsutil/net/net_darwin.go | 284 ++ .../shirou/gopsutil/net/net_fallback.go | 49 + .../shirou/gopsutil/net/net_freebsd.go | 125 + .../shirou/gopsutil/net/net_linux.go | 791 +++++ .../shirou/gopsutil/net/net_openbsd.go | 312 ++ .../shirou/gopsutil/net/net_unix.go | 96 + .../shirou/gopsutil/net/net_windows.go | 120 + .../shirou/gopsutil/process/process.go | 241 ++ .../shirou/gopsutil/process/process_darwin.go | 647 ++++ .../gopsutil/process/process_darwin_386.go | 234 ++ .../gopsutil/process/process_darwin_amd64.go | 234 ++ .../gopsutil/process/process_fallback.go | 304 ++ .../gopsutil/process/process_freebsd.go | 480 +++ .../gopsutil/process/process_freebsd_386.go | 192 ++ .../gopsutil/process/process_freebsd_amd64.go | 192 ++ .../gopsutil/process/process_freebsd_arm.go | 192 ++ .../shirou/gopsutil/process/process_linux.go | 1257 ++++++++ .../gopsutil/process/process_openbsd.go | 510 ++++ .../gopsutil/process/process_openbsd_amd64.go | 200 ++ .../shirou/gopsutil/process/process_posix.go | 140 + .../gopsutil/process/process_windows.go | 707 +++++ .../gopsutil/process/process_windows_386.go | 16 + .../gopsutil/process/process_windows_amd64.go | 16 + .../shirou/gopsutil/process/types_darwin.go | 160 + .../shirou/gopsutil/process/types_freebsd.go | 95 + .../shirou/gopsutil/process/types_openbsd.go | 103 + vendor/github.com/shirou/w32/AUTHORS | 16 + vendor/github.com/shirou/w32/LICENSE | 23 + vendor/github.com/shirou/w32/README.md | 33 + vendor/github.com/shirou/w32/advapi32.go | 301 ++ vendor/github.com/shirou/w32/comctl32.go | 111 + vendor/github.com/shirou/w32/comdlg32.go | 40 + vendor/github.com/shirou/w32/constants.go | 2661 +++++++++++++++++ vendor/github.com/shirou/w32/dwmapi.go | 256 ++ vendor/github.com/shirou/w32/gdi32.go | 511 ++++ vendor/github.com/shirou/w32/gdiplus.go | 177 ++ vendor/github.com/shirou/w32/idispatch.go | 45 + vendor/github.com/shirou/w32/istream.go | 33 + vendor/github.com/shirou/w32/iunknown.go | 29 + vendor/github.com/shirou/w32/kernel32.go | 316 ++ vendor/github.com/shirou/w32/ole32.go | 65 + vendor/github.com/shirou/w32/oleaut32.go | 50 + vendor/github.com/shirou/w32/opengl32.go | 74 + vendor/github.com/shirou/w32/psapi.go | 27 + vendor/github.com/shirou/w32/shell32.go | 155 + vendor/github.com/shirou/w32/typedef.go | 901 ++++++ vendor/github.com/shirou/w32/user32.go | 950 ++++++ vendor/github.com/shirou/w32/utils.go | 203 ++ vendor/github.com/shirou/w32/vars.go | 13 + 106 files changed, 20097 insertions(+), 90 deletions(-) create mode 100644 vendor/github.com/mitchellh/go-ps/.gitignore create mode 100644 vendor/github.com/mitchellh/go-ps/.travis.yml create mode 100644 vendor/github.com/mitchellh/go-ps/LICENSE.md create mode 100644 vendor/github.com/mitchellh/go-ps/README.md create mode 100644 vendor/github.com/mitchellh/go-ps/Vagrantfile create mode 100644 vendor/github.com/mitchellh/go-ps/process.go create mode 100644 vendor/github.com/mitchellh/go-ps/process_darwin.go create mode 100644 vendor/github.com/mitchellh/go-ps/process_freebsd.go create mode 100644 vendor/github.com/mitchellh/go-ps/process_linux.go create mode 100644 vendor/github.com/mitchellh/go-ps/process_solaris.go create mode 100644 vendor/github.com/mitchellh/go-ps/process_unix.go create mode 100644 vendor/github.com/mitchellh/go-ps/process_windows.go create mode 100644 vendor/github.com/shirou/gopsutil/cpu/cpu.go create mode 100644 vendor/github.com/shirou/gopsutil/cpu/cpu_darwin.go create mode 100644 vendor/github.com/shirou/gopsutil/cpu/cpu_darwin_cgo.go create mode 100644 vendor/github.com/shirou/gopsutil/cpu/cpu_darwin_nocgo.go create mode 100644 vendor/github.com/shirou/gopsutil/cpu/cpu_fallback.go create mode 100644 vendor/github.com/shirou/gopsutil/cpu/cpu_freebsd.go create mode 100644 vendor/github.com/shirou/gopsutil/cpu/cpu_freebsd_386.go create mode 100644 vendor/github.com/shirou/gopsutil/cpu/cpu_freebsd_amd64.go create mode 100644 vendor/github.com/shirou/gopsutil/cpu/cpu_linux.go create mode 100644 vendor/github.com/shirou/gopsutil/cpu/cpu_openbsd.go create mode 100644 vendor/github.com/shirou/gopsutil/cpu/cpu_solaris.go create mode 100644 vendor/github.com/shirou/gopsutil/cpu/cpu_windows.go create mode 100644 vendor/github.com/shirou/gopsutil/host/host.go create mode 100644 vendor/github.com/shirou/gopsutil/host/host_darwin.go create mode 100644 vendor/github.com/shirou/gopsutil/host/host_darwin_386.go create mode 100644 vendor/github.com/shirou/gopsutil/host/host_darwin_amd64.go create mode 100644 vendor/github.com/shirou/gopsutil/host/host_fallback.go create mode 100644 vendor/github.com/shirou/gopsutil/host/host_freebsd.go create mode 100644 vendor/github.com/shirou/gopsutil/host/host_freebsd_386.go create mode 100644 vendor/github.com/shirou/gopsutil/host/host_freebsd_amd64.go create mode 100644 vendor/github.com/shirou/gopsutil/host/host_freebsd_arm.go create mode 100644 vendor/github.com/shirou/gopsutil/host/host_linux.go create mode 100644 vendor/github.com/shirou/gopsutil/host/host_linux_386.go create mode 100644 vendor/github.com/shirou/gopsutil/host/host_linux_amd64.go create mode 100644 vendor/github.com/shirou/gopsutil/host/host_linux_arm.go create mode 100644 vendor/github.com/shirou/gopsutil/host/host_linux_arm64.go create mode 100644 vendor/github.com/shirou/gopsutil/host/host_linux_mips.go create mode 100644 vendor/github.com/shirou/gopsutil/host/host_linux_mips64.go create mode 100644 vendor/github.com/shirou/gopsutil/host/host_linux_mips64le.go create mode 100644 vendor/github.com/shirou/gopsutil/host/host_linux_mipsle.go create mode 100644 vendor/github.com/shirou/gopsutil/host/host_linux_ppc64le.go create mode 100644 vendor/github.com/shirou/gopsutil/host/host_linux_s390x.go create mode 100644 vendor/github.com/shirou/gopsutil/host/host_openbsd.go create mode 100644 vendor/github.com/shirou/gopsutil/host/host_openbsd_amd64.go create mode 100644 vendor/github.com/shirou/gopsutil/host/host_solaris.go create mode 100644 vendor/github.com/shirou/gopsutil/host/host_windows.go create mode 100644 vendor/github.com/shirou/gopsutil/host/types_darwin.go create mode 100644 vendor/github.com/shirou/gopsutil/host/types_freebsd.go create mode 100644 vendor/github.com/shirou/gopsutil/host/types_linux.go create mode 100644 vendor/github.com/shirou/gopsutil/host/types_openbsd.go create mode 100644 vendor/github.com/shirou/gopsutil/net/net.go create mode 100644 vendor/github.com/shirou/gopsutil/net/net_darwin.go create mode 100644 vendor/github.com/shirou/gopsutil/net/net_fallback.go create mode 100644 vendor/github.com/shirou/gopsutil/net/net_freebsd.go create mode 100644 vendor/github.com/shirou/gopsutil/net/net_linux.go create mode 100644 vendor/github.com/shirou/gopsutil/net/net_openbsd.go create mode 100644 vendor/github.com/shirou/gopsutil/net/net_unix.go create mode 100644 vendor/github.com/shirou/gopsutil/net/net_windows.go create mode 100644 vendor/github.com/shirou/gopsutil/process/process.go create mode 100644 vendor/github.com/shirou/gopsutil/process/process_darwin.go create mode 100644 vendor/github.com/shirou/gopsutil/process/process_darwin_386.go create mode 100644 vendor/github.com/shirou/gopsutil/process/process_darwin_amd64.go create mode 100644 vendor/github.com/shirou/gopsutil/process/process_fallback.go create mode 100644 vendor/github.com/shirou/gopsutil/process/process_freebsd.go create mode 100644 vendor/github.com/shirou/gopsutil/process/process_freebsd_386.go create mode 100644 vendor/github.com/shirou/gopsutil/process/process_freebsd_amd64.go create mode 100644 vendor/github.com/shirou/gopsutil/process/process_freebsd_arm.go create mode 100644 vendor/github.com/shirou/gopsutil/process/process_linux.go create mode 100644 vendor/github.com/shirou/gopsutil/process/process_openbsd.go create mode 100644 vendor/github.com/shirou/gopsutil/process/process_openbsd_amd64.go create mode 100644 vendor/github.com/shirou/gopsutil/process/process_posix.go create mode 100644 vendor/github.com/shirou/gopsutil/process/process_windows.go create mode 100644 vendor/github.com/shirou/gopsutil/process/process_windows_386.go create mode 100644 vendor/github.com/shirou/gopsutil/process/process_windows_amd64.go create mode 100644 vendor/github.com/shirou/gopsutil/process/types_darwin.go create mode 100644 vendor/github.com/shirou/gopsutil/process/types_freebsd.go create mode 100644 vendor/github.com/shirou/gopsutil/process/types_openbsd.go create mode 100644 vendor/github.com/shirou/w32/AUTHORS create mode 100644 vendor/github.com/shirou/w32/LICENSE create mode 100644 vendor/github.com/shirou/w32/README.md create mode 100644 vendor/github.com/shirou/w32/advapi32.go create mode 100644 vendor/github.com/shirou/w32/comctl32.go create mode 100644 vendor/github.com/shirou/w32/comdlg32.go create mode 100644 vendor/github.com/shirou/w32/constants.go create mode 100644 vendor/github.com/shirou/w32/dwmapi.go create mode 100644 vendor/github.com/shirou/w32/gdi32.go create mode 100644 vendor/github.com/shirou/w32/gdiplus.go create mode 100644 vendor/github.com/shirou/w32/idispatch.go create mode 100644 vendor/github.com/shirou/w32/istream.go create mode 100644 vendor/github.com/shirou/w32/iunknown.go create mode 100644 vendor/github.com/shirou/w32/kernel32.go create mode 100644 vendor/github.com/shirou/w32/ole32.go create mode 100644 vendor/github.com/shirou/w32/oleaut32.go create mode 100644 vendor/github.com/shirou/w32/opengl32.go create mode 100644 vendor/github.com/shirou/w32/psapi.go create mode 100644 vendor/github.com/shirou/w32/shell32.go create mode 100644 vendor/github.com/shirou/w32/typedef.go create mode 100644 vendor/github.com/shirou/w32/user32.go create mode 100644 vendor/github.com/shirou/w32/utils.go create mode 100644 vendor/github.com/shirou/w32/vars.go diff --git a/Gopkg.lock b/Gopkg.lock index 16e821df4a87..28f7878e5c9a 100644 --- a/Gopkg.lock +++ b/Gopkg.lock @@ -222,6 +222,12 @@ revision = "53b9af5a45362a6f2896cfa39cc17d17ba9667ea" source = "github.com/golangci/dupl" +[[projects]] + branch = "master" + name = "github.com/mitchellh/go-ps" + packages = ["."] + revision = "4fdf99ab29366514c69ccccddab5dc58b8d84062" + [[projects]] branch = "master" name = "github.com/mitchellh/mapstructure" @@ -259,12 +265,22 @@ [[projects]] name = "github.com/shirou/gopsutil" packages = [ + "cpu", + "host", "internal/common", - "mem" + "mem", + "net", + "process" ] revision = "c95755e4bcd7a62bb8bd33f3a597a7c7f35e2cf3" version = "v2.18.04" +[[projects]] + branch = "master" + name = "github.com/shirou/w32" + packages = ["."] + revision = "bb4de0191aa41b5507caa14b0650cdbddcd9280b" + [[projects]] name = "github.com/sirupsen/logrus" packages = ["."] @@ -395,6 +411,6 @@ [solve-meta] analyzer-name = "dep" analyzer-version = 1 - inputs-digest = "04f4609b2c6a2c0929f3ec80a6ad7877b0c0d18a4980f80250eebc5f7b8567c0" + inputs-digest = "f75bddb805db581bbdc751784b540bc476179ed3d918cac98b870bb8c48a26aa" solver-name = "gps-cdcl" solver-version = 1 diff --git a/Gopkg.toml b/Gopkg.toml index 1c8af1e7f08d..b10165f702eb 100644 --- a/Gopkg.toml +++ b/Gopkg.toml @@ -73,3 +73,7 @@ [[constraint]] name = "github.com/spf13/viper" version = "1.0.2" + +[[constraint]] + branch = "master" + name = "github.com/mitchellh/go-ps" diff --git a/README.md b/README.md index 7095a247c90e..2e840b6fdeb4 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ # GolangCI-Lint [![Build Status](https://travis-ci.com/golangci/golangci-lint.svg?branch=master)](https://travis-ci.com/golangci/golangci-lint) -GolangCI-Lint is a linters aggregator. It is [fast](#performance) (2-6 times faster than gometalinter), [easy to integrate and use](#issues-options), has [nice output](quick-start) and has minimum count of false positives. +GolangCI-Lint is a linters aggregator. It is [fast](#performance) (2-7 times faster than gometalinter), [easy to integrate and use](#issues-options), has [nice output](quick-start) and has minimum count of false positives. Sponsored by [GolangCI.com](https://golangci.com): SaaS service for running linters on Github pull requests. Free for Open Source. @@ -94,7 +94,7 @@ $ golangci-lint run --disable-all -E errcheck # Comparison ## `golangci-lint` vs `gometalinter` GolangCI-Lint was created to fix next issues with `gometalinter`: -1. Slow work: `gometalinter` usually works for minutes in average projects. GolangCI-Lint works [2-6x times faster](#performance) by [reusing work](#internals). +1. Slow work: `gometalinter` usually works for minutes in average projects. GolangCI-Lint works [2-7x times faster](#performance) by [reusing work](#internals). 2. Huge memory consumption: parallel linters don't share the same program representation and can eat `n` times more memory (`n` - concurrency). GolangCI-Lint fixes it by sharing representation. 3. Can't set honest concurrency: if you set it to `n` it can take `n+x` 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 fully control them. Configured concurrency will be honest. This issue is important because often you'd like to set concurrency to CPUs count minus one to save one CPU for example for IDE. It concurrency isn't correct you will have troubles using IDE while analyzing code. @@ -112,7 +112,9 @@ This issue is important because often you'd like to set concurrency to CPUs coun # 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 concurrency for linters was default: number of cores. Benchmark runs and measures timings automatically, it's code is [here](https://github.com/golangci/golangci-lint/blob/master/pkg/enabled_linters_test.go) (`BenchmarkWithGometalinter`). -## Default Mode +We measure peak memory usage (RSS) by measurement of processes RSS every 5 ms. + +## Comparison with gometalinter We compare golangci-lint and gometalinter in default mode, but explicitly specify all linters to enable because of small differences in default configuration. ```bash $ golangci-lint run --no-config --issues-exit-code=0 --deadline=30m \ @@ -127,38 +129,20 @@ $ gometalinter --deadline=30m --vendor --cyclo-over=30 --dupl-threshold=150 \ ./... ``` -| Repository | GolangCI Lint Time | GolangCI Is Faster In | -| ---------- | ------------------ | --------------------- | -| self repo, 4.4 kLoC | 9.1s | **6.6x** | -| gometalinter repo, 3.8 kLoC | 5.1s | **4.9x** | -| hugo, 69 kLoC | 12.4s | **5.8x** | -| go source, 1300 kLoC | 3m15s | **1.8x** | - -On average golangci-lint is 4.8 times faster than gometalinter. Maximum difference is in -self repo: 6.6 times faster, minimum difference is in go source code repo: 1.8 times faster. - -## Fast Mode -We compare golangci-lint and gometalinter in fast mode (`--fast`), but don't use option `--fast` because it differs a little. -Instead we configure common linters from this option. -```bash -$ golangci-lint run --no-config --issues-exit-code=0 --deadline=30m \ - --disable-all --enable=govet --enable=dupl --enable=goconst --enable=gocyclo --enable=golint --enable=ineffassign -$ gometalinter --deadline=30m --vendor --cyclo-over=30 --dupl-threshold=150 \ - --exclude= --skip=testdata --skip=builtin \ - --disable-all --enable=vet --enable=vetshadow -enable=dupl --enable=goconst --enable=gocyclo --enable=golint --enable=ineffassign \ - ./... -``` - -| Repository | GolangCI Lint Time | GolangCI Is Faster In | -| ---------- | ------------------ | --------------------- | -| self repo, 4.4 kLoC | 0.4s | **3.1x** | -| gometalinter repo, 3.8 kLoC | 0.2s | **1.9x** | -| hugo, 69 kLoC | 1.6s | **4x** | -| go source, 1300 kLoC | 35.4s | **1.2x** | +| 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 | 1.5x | +| self repo, 4 kLoC | 12s | **7.5x** | 1.2GB | 1.7x | +| beego, 50 kLoC | 10s | **4.2x** | 1.4GB | 1.1x | +| hugo, 70 kLoC | 15s | **6.1x** | 1.6GB | 1.8x | +| consul, 127 kLoC | 58s | **4x** | 2.7GB | 1.7x | +| terraform, 190 kLoC | 2m13s | **1.6x** | 4.8GB | 1x | +| go-ethereum, 250 kLoC | 33s | **5x** | 3.6GB | 1x | +| go source, 1300 kLoC | 2m45s | **2x** | 4.7GB | 1x | -On average golangci-lint is 2.5 times faster than gometalinter. Maximum difference is in -self repo: 3.1 times faster, minimum difference is in go source code repo: 20% faster. +**On average golangci-lint is 4.6 times faster** than gometalinter. Maximum difference is in +self repo: **7.5 times faster**, minimum difference is in terraform source code repo: 1.8 times faster. # Supported Linters To see a list of supported linters and which linters are enabled/disabled by default execute command diff --git a/pkg/enabled_linters_test.go b/pkg/enabled_linters_test.go index c711b6f2b984..5262300527f1 100644 --- a/pkg/enabled_linters_test.go +++ b/pkg/enabled_linters_test.go @@ -14,7 +14,8 @@ import ( "time" "github.com/golangci/golangci-lint/pkg/config" - "github.com/shirou/gopsutil/mem" + gops "github.com/mitchellh/go-ps" + "github.com/shirou/gopsutil/process" "github.com/sirupsen/logrus" "github.com/stretchr/testify/assert" ) @@ -125,18 +126,6 @@ func getBenchLintersArgs() []string { }, getBenchLintersArgsNoMegacheck()...) } -func getBenchFastLintersArgs() []string { - return []string{ - "--enable=dupl", - "--enable=goconst", - "--enable=gocyclo", - "--enable=golint", - "--enable=ineffassign", - // don't add gas because gometalinter uses old, fast and not working for me version of it. - // golangci-lint uses new and slower version of it. - } -} - func getGometalinterCommonArgs() []string { return []string{ "--deadline=30m", @@ -152,19 +141,25 @@ func getGometalinterCommonArgs() []string { } } +func printCommand(cmd string, args ...string) { + if os.Getenv("PRINT_CMD") != "1" { + return + } + quotedArgs := []string{} + for _, a := range args { + quotedArgs = append(quotedArgs, strconv.Quote(a)) + } + + logrus.Warnf("%s %s", cmd, strings.Join(quotedArgs, " ")) +} + func runGometalinter(b *testing.B) { args := []string{} args = append(args, getGometalinterCommonArgs()...) args = append(args, getBenchLintersArgs()...) args = append(args, "./...") - _ = exec.Command("gometalinter", args...).Run() -} -func runGometalinterFast(b *testing.B) { - args := []string{} - args = append(args, getGometalinterCommonArgs()...) - args = append(args, getBenchFastLintersArgs()...) - args = append(args, "./...") + printCommand("gometalinter", args...) _ = exec.Command("gometalinter", args...).Run() } @@ -175,15 +170,7 @@ func getGolangciLintCommonArgs() []string { func runGolangciLint(b *testing.B) { args := getGolangciLintCommonArgs() args = append(args, getBenchLintersArgs()...) - out, err := exec.Command("golangci-lint", args...).CombinedOutput() - if err != nil { - b.Fatalf("can't run golangci-lint: %s, %s", err, out) - } -} - -func runGolangciLintFast(b *testing.B) { - args := getGolangciLintCommonArgs() - args = append(args, getBenchFastLintersArgs()...) + printCommand("golangci-lint", args...) out, err := exec.Command("golangci-lint", args...).CombinedOutput() if err != nil { b.Fatalf("can't run golangci-lint: %s, %s", err, out) @@ -206,20 +193,53 @@ func getGoLinesTotalCount(b *testing.B) int { return n } -func getUsedMemoryMb(b *testing.B) int { - v, err := mem.VirtualMemory() +func getLinterMemoryMB(b *testing.B, progName string) (int, error) { + processes, err := gops.Processes() if err != nil { - b.Fatalf("can't get usedmemory: %s", err) + b.Fatalf("Can't get processes: %s", err) + } + + var progPID int + for _, p := range processes { + if p.Executable() == progName { + progPID = p.Pid() + break + } } + if progPID == 0 { + return 0, fmt.Errorf("no process") + } + + allProgPIDs := []int{progPID} + for _, p := range processes { + if p.PPid() == progPID { + allProgPIDs = append(allProgPIDs, p.Pid()) + } + } + + var totalProgMemBytes uint64 + for _, pid := range allProgPIDs { + p, err := process.NewProcess(int32(pid)) + if err != nil { + continue // subprocess could die + } + + mi, err := p.MemoryInfo() + if err != nil { + continue + } - return int(v.Used / 1024 / 1024) + totalProgMemBytes += mi.RSS + } + + return int(totalProgMemBytes / 1024 / 1024), nil } -func trackPeakMemoryUsage(b *testing.B, doneCh chan struct{}) chan int { +func trackPeakMemoryUsage(b *testing.B, doneCh <-chan struct{}, progName string) chan int { resCh := make(chan int) go func() { var peakUsedMemMB int - t := time.NewTicker(time.Millisecond * 50) + t := time.NewTicker(time.Millisecond * 5) defer t.Stop() for { @@ -231,7 +251,10 @@ func trackPeakMemoryUsage(b *testing.B, doneCh chan struct{}) chan int { case <-t.C: } - m := getUsedMemoryMb(b) + m, err := getLinterMemoryMB(b, progName) + if err != nil { + continue + } if m > peakUsedMemMB { peakUsedMemMB = m } @@ -240,24 +263,38 @@ func trackPeakMemoryUsage(b *testing.B, doneCh chan struct{}) chan int { return resCh } -func runBench(b *testing.B, run func(*testing.B), format string, args ...interface{}) { - startUsedMemMB := getUsedMemoryMb(b) +type runResult struct { + peakMemMB int + duration time.Duration +} + +func compare(b *testing.B, gometalinterRun, golangciLintRun func(*testing.B), repoName, mode string, kLOC int) { // nolint + gometalinterRes := runOne(b, gometalinterRun, "gometalinter") + golangciLintRes := runOne(b, golangciLintRun, "golangci-lint") + + if mode != "" { + mode = " " + mode + } + logrus.Warnf("%s (%d kLoC): golangci-lint%s: time: %s, %.1f times faster; memory: %dMB, %.1f times less", + repoName, kLOC, mode, + golangciLintRes.duration, gometalinterRes.duration.Seconds()/golangciLintRes.duration.Seconds(), + golangciLintRes.peakMemMB, float64(gometalinterRes.peakMemMB)/float64(golangciLintRes.peakMemMB), + ) +} + +func runOne(b *testing.B, run func(*testing.B), progName string) *runResult { doneCh := make(chan struct{}) - peakMemCh := trackPeakMemoryUsage(b, doneCh) - name := fmt.Sprintf(format, args...) - b.Run(name, func(b *testing.B) { - for i := 0; i < b.N; i++ { - run(b) - } - }) + peakMemCh := trackPeakMemoryUsage(b, doneCh, progName) + startedAt := time.Now() + run(b) + duration := time.Since(startedAt) close(doneCh) + peakUsedMemMB := <-peakMemCh - var linterPeakMemUsage int - if peakUsedMemMB > startUsedMemMB { - linterPeakMemUsage = peakUsedMemMB - startUsedMemMB + return &runResult{ + peakMemMB: peakUsedMemMB, + duration: duration, } - logrus.Warnf("%s: start used mem is %dMB, peak used mem is %dMB, linter peak mem usage is %dMB", - name, startUsedMemMB, peakUsedMemMB, linterPeakMemUsage) } func BenchmarkWithGometalinter(b *testing.B) { @@ -280,6 +317,22 @@ func BenchmarkWithGometalinter(b *testing.B) { name: "hugo", prepare: prepareGithubProject("gohugoio", "hugo"), }, + { + name: "go-ethereum", + prepare: prepareGithubProject("ethereum", "go-ethereum"), + }, + { + name: "beego", + prepare: prepareGithubProject("astaxie", "beego"), + }, + { + name: "terraform", + prepare: prepareGithubProject("hashicorp", "terraform"), + }, + { + name: "consul", + prepare: prepareGithubProject("hashicorp", "consul"), + }, { name: "go source code", prepare: prepareGoSource, @@ -289,10 +342,6 @@ func BenchmarkWithGometalinter(b *testing.B) { bc.prepare(b) lc := getGoLinesTotalCount(b) - runBench(b, runGometalinterFast, "%s/gometalinter --fast (%d lines of code)", bc.name, lc) - runBench(b, runGolangciLintFast, "%s/golangci-lint fast (%d lines of code)", bc.name, lc) - - runBench(b, runGometalinter, "%s/gometalinter (%d lines of code)", bc.name, lc) - runBench(b, runGolangciLint, "%s/golangci-lint (%d lines of code)", bc.name, lc) + compare(b, runGometalinter, runGolangciLint, bc.name, "", lc/1000) } } diff --git a/vendor/github.com/mitchellh/go-ps/.gitignore b/vendor/github.com/mitchellh/go-ps/.gitignore new file mode 100644 index 000000000000..a977916f6583 --- /dev/null +++ b/vendor/github.com/mitchellh/go-ps/.gitignore @@ -0,0 +1 @@ +.vagrant/ diff --git a/vendor/github.com/mitchellh/go-ps/.travis.yml b/vendor/github.com/mitchellh/go-ps/.travis.yml new file mode 100644 index 000000000000..8f794f71da43 --- /dev/null +++ b/vendor/github.com/mitchellh/go-ps/.travis.yml @@ -0,0 +1,4 @@ +language: go + +go: + - 1.2.1 diff --git a/vendor/github.com/mitchellh/go-ps/LICENSE.md b/vendor/github.com/mitchellh/go-ps/LICENSE.md new file mode 100644 index 000000000000..229851590442 --- /dev/null +++ b/vendor/github.com/mitchellh/go-ps/LICENSE.md @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2014 Mitchell Hashimoto + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/vendor/github.com/mitchellh/go-ps/README.md b/vendor/github.com/mitchellh/go-ps/README.md new file mode 100644 index 000000000000..8e8baf9d2605 --- /dev/null +++ b/vendor/github.com/mitchellh/go-ps/README.md @@ -0,0 +1,34 @@ +# Process List Library for Go + +go-ps is a library for Go that implements OS-specific APIs to list and +manipulate processes in a platform-safe way. The library can find and +list processes on Linux, Mac OS X, Solaris, and Windows. + +If you're new to Go, this library has a good amount of advanced Go educational +value as well. It uses some advanced features of Go: build tags, accessing +DLL methods for Windows, cgo for Darwin, etc. + +How it works: + + * **Darwin** uses the `sysctl` syscall to retrieve the process table. + * **Unix** uses the procfs at `/proc` to inspect the process tree. + * **Windows** uses the Windows API, and methods such as + `CreateToolhelp32Snapshot` to get a point-in-time snapshot of + the process table. + +## Installation + +Install using standard `go get`: + +``` +$ go get github.com/mitchellh/go-ps +... +``` + +## TODO + +Want to contribute? Here is a short TODO list of things that aren't +implemented for this library that would be nice: + + * FreeBSD support + * Plan9 support diff --git a/vendor/github.com/mitchellh/go-ps/Vagrantfile b/vendor/github.com/mitchellh/go-ps/Vagrantfile new file mode 100644 index 000000000000..61662ab1e3e7 --- /dev/null +++ b/vendor/github.com/mitchellh/go-ps/Vagrantfile @@ -0,0 +1,43 @@ +# -*- mode: ruby -*- +# vi: set ft=ruby : + +# Vagrantfile API/syntax version. Don't touch unless you know what you're doing! +VAGRANTFILE_API_VERSION = "2" + +Vagrant.configure(VAGRANTFILE_API_VERSION) do |config| + config.vm.box = "chef/ubuntu-12.04" + + config.vm.provision "shell", inline: $script + + ["vmware_fusion", "vmware_workstation"].each do |p| + config.vm.provider "p" do |v| + v.vmx["memsize"] = "1024" + v.vmx["numvcpus"] = "2" + v.vmx["cpuid.coresPerSocket"] = "1" + end + end +end + +$script = <