Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Args in empty no-op functions cause allocations #30953

Closed
fmstephe opened this issue Mar 20, 2019 · 3 comments
Closed

Args in empty no-op functions cause allocations #30953

fmstephe opened this issue Mar 20, 2019 · 3 comments

Comments

@fmstephe
Copy link

fmstephe commented Mar 20, 2019

What version of Go are you using (go version)?

go version go1.12 darwin/amd64

Does this issue reproduce with the latest release?

Yes, also tried it with 1.12.1

What operating system and processor architecture are you using (go env)?

go env Output
$ GOARCH="amd64"
GOBIN="/Users/fmstephe/golang/go/bin"
GOCACHE="/Users/fmstephe/Library/Caches/go-build"
GOEXE=""
GOFLAGS=""
GOHOSTARCH="amd64"
GOHOSTOS="darwin"
GOOS="darwin"
GOPATH="/Users/fmstephe/golang/proj"
GOPROXY=""
GORACE=""
GOROOT="/Users/fmstephe/golang/go"
GOTMPDIR=""
GOTOOLDIR="/Users/fmstephe/golang/go/pkg/tool/darwin_amd64"
GCCGO="gccgo"
CC="clang"
CXX="clang++"
CGO_ENABLED="1"
GOMOD=""
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 -fno-caret-diagnostics -Qunused-arguments -fmessage-length=0 -fdebug-prefix-map=/var/folders/5b/mmf8wp713214hcyzh0vdcjph0000gn/T/go-build469919168=/tmp/go-build -gno-record-gcc-switches -fno-common"

What did you do?

This benchmark allocates on every loop.

https://gist.github.com/fmstephe/a23ddff062f3b96df5e634ccf21e0106

func BenchmarkDebugNoop(b *testing.B) {
	b.ReportAllocs()
	for i := 0; i < b.N; i++ {
		Debugf("This does nothing %d", i)
	}
}

func BenchmarkDebugNoop_NoArgs(b *testing.B) {
	b.ReportAllocs()
	for i := 0; i < b.N; i++ {
		Debugf("This is also does nothing")
	}
}

func Debugf(s string, a ...interface{}) {} // disable debug logs unless `debug` tag is provided

What did you expect to see?

No allocations.

What did you see instead?

Allocations. I would like the compiler to observe that the allocating args are unused and not allocate.

@fmstephe
Copy link
Author

Curiously this seems to be tied to the use of a vararg in Debugf. With just a straight a interface{} it doesn't allocate at all.

package main

import (
	"testing"
)
/*
goos: darwin
goarch: amd64
pkg: github.com/fmstephe/test_empty_method
BenchmarkDebugNoop-4            2000000000               0.26 ns/op            0 B/op          0 allocs/op
BenchmarkDebugNoop_NoArgs-4     2000000000               0.26 ns/op            0 B/op          0 allocs/op
PASS
*/

func BenchmarkDebugNoop(b *testing.B) {
	b.ReportAllocs()
	for i := 0; i < b.N; i++ {
		Debugf("This does nothing %d", i)
	}
}

func BenchmarkDebugNoop_NoArgs(b *testing.B) {
	b.ReportAllocs()
	for i := 0; i < b.N; i++ {
		Debugf("This is also does nothing", nil)
	}
}

func Debugf(s string, a interface{}) {} // disable debug logs unless `debug` tag is provided

@cherrymui
Copy link
Member

Looks like a dup of #30898 ?

@fmstephe
Copy link
Author

Closing as dupe of #30898

@golang golang locked and limited conversation to collaborators Mar 19, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

3 participants