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

cmd/compile: idiomatic (returned) iterators are slower than unidiomatic, direct iterators #69411

Closed
eliasnaur opened this issue Sep 11, 2024 · 4 comments
Assignees
Labels
compiler/runtime Issues related to the Go compiler and/or runtime. NeedsFix The path to resolution is known, but the work has not been done. Performance
Milestone

Comments

@eliasnaur
Copy link
Contributor

eliasnaur commented Sep 11, 2024

Go version

go version devel go1.24-fc968d49c1 Fri Aug 30 11:42:55 2024 -0400 darwin/arm64 (with CL 609095)

Output of go env in your module/workspace:

GO111MODULE=''
GOARCH='arm64'
GOBIN=''
GOCACHE='/Users/a/Library/Caches/go-build'
GOENV='/Users/a/Library/Application Support/go/env'
GOEXE=''
GOEXPERIMENT=''
GOFLAGS=''
GOHOSTARCH='arm64'
GOHOSTOS='darwin'
GOINSECURE=''
GOMODCACHE='/Users/a/go/pkg/mod'
GONOPROXY=''
GONOSUMDB=''
GOOS='darwin'
GOPATH='/Users/a/go'
GOPRIVATE=''
GOPROXY='https://proxy.golang.org,direct'
GOROOT='/Users/a/proj/goroot'
GOSUMDB='sum.golang.org'
GOTMPDIR=''
GOTOOLCHAIN='auto'
GOTOOLDIR='/Users/a/proj/goroot/pkg/tool/darwin_arm64'
GOVCS=''
GOVERSION='devel go1.24-fc968d49c1 Fri Aug 30 11:42:55 2024 -0400'
GODEBUG=''
GOTELEMETRY='local'
GOTELEMETRYDIR='/Users/a/Library/Application Support/go/telemetry'
GCCGO='gccgo'
GOARM64='v8.0'
AR='ar'
CC='clang'
CXX='clang++'
CGO_ENABLED='1'
GOMOD='/Users/a/Downloads/itergarbage/go.mod'
GOWORK=''
CGO_CFLAGS='-O2 -g'
CGO_CPPFLAGS=''
CGO_CXXFLAGS='-O2 -g'
CGO_FFLAGS='-O2 -g'
CGO_LDFLAGS='-O2 -g'
PKG_CONFIG='pkg-config'
GOGCCFLAGS='-fPIC -arch arm64 -pthread -fno-caret-diagnostics -Qunused-arguments -fmessage-length=0 -ffile-prefix-map=/var/folders/9c/t7b8z6m93sxgr4m4m4kbvllw0000gn/T/go-build4265899566=/tmp/go-build -gno-record-gcc-switches -fno-common'

What did you do?

Benchmarked https://go.dev/play/p/bNomKLr7kQX that compared the performance, in particular the allocations, of 3 ways to implement a nested iterator. The benchmarks are synthetic, because they're extracted from a larger project with more complex iterators.

$ go test -bench . -benchmem
goos: darwin
goarch: arm64
pkg: example.com
cpu: Apple M1 Pro
BenchmarkFormatIdiomatic-8         	39902122	        29.64 ns/op	      24 B/op	       2 allocs/op
BenchmarkFormatterIdiomatic-8      	38252599	        29.33 ns/op	      24 B/op	       2 allocs/op
BenchmarkFormatterNonIdiomatic-8   	381599230	         3.155 ns/op	       0 B/op	       0 allocs/op
PASS
ok  	example.com	4.857s

What did you see happen?

The idiomatic way to create an iterator is to return it from a function or method. In my example, the iterator I want is

func FormatIdiomatic() iter.Seq[rune]

however, that and its method variant,

func (f *Formatter) RunesIdiomatic() iter.Seq[rune]

both result in allocations.

Notably, the unidiomatic

func (f *Formatter) RunesNonIdiomatic(yield func(rune) bool)

doesn't allocate and in general these "direct" iterators runs significantly faster than their idiomatic siblings.

What did you expect to see?

No allocations from idiomatic iterators, even if nested.

Note that I ran the tests with https://go-review.googlesource.com/c/go/+/609095 applied, which didn't seem to make a difference.

Related: #66469 and #69015

@gopherbot gopherbot added the compiler/runtime Issues related to the Go compiler and/or runtime. label Sep 11, 2024
@gabyhelp
Copy link

Related Issues and Documentation

(Emoji vote if this was helpful or unhelpful; more detailed feedback welcome in this discussion.)

@eliasnaur eliasnaur changed the title runtime: idiomatic (returned) iterators are slower than unidiomatic, direct iterators cmd/compile: idiomatic (returned) iterators are slower than unidiomatic, direct iterators Sep 12, 2024
@timothy-king timothy-king added this to the Backlog milestone Sep 12, 2024
@timothy-king
Copy link
Contributor

cc @dr2chase

@timothy-king timothy-king added the NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one. label Sep 12, 2024
@mknyszek mknyszek moved this from Todo to All-But-Submitted in Go Compiler / Runtime Sep 18, 2024
@mknyszek mknyszek moved this from All-But-Submitted to Todo in Go Compiler / Runtime Sep 18, 2024
@dr2chase
Copy link
Contributor

dr2chase commented Nov 5, 2024

This is an inliner-problem, not a cost problem -- it still reproduces with the budget set at 1000.

@gopherbot
Copy link
Contributor

Change https://go.dev/cl/629195 mentions this issue: cmd/compile: strongly favor closure inlining

@github-project-automation github-project-automation bot moved this from Todo to Done in Go Compiler / Runtime Nov 19, 2024
@dmitshur dmitshur modified the milestones: Backlog, Go1.24 Nov 22, 2024
@dmitshur dmitshur added NeedsFix The path to resolution is known, but the work has not been done. and removed NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one. labels Nov 22, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
compiler/runtime Issues related to the Go compiler and/or runtime. NeedsFix The path to resolution is known, but the work has not been done. Performance
Projects
Development

No branches or pull requests

7 participants