4 ms·
It is very difficult to avoid putting strings on the heap in go. I used the built in escape analysis tools and made sure I only use a constant amount of memory
by fsmv 1y ago
It is very difficult to avoid putting strings on the heap in go. I used the built in escape analysis tools and made sure I only use a constant amount of memory in the loop in my short https://github.com/fsmv/in.go https://github.com/fsmv/in.go progress bar program.
The biggest problem is any string you pass as an argument to the fmt functions is moved onto the heap because interface{} is always counted as escaped from the stack (https://github.com/golang/go/issues/8618 https://github.com/golang/go/issues/8618).
- typical182 1y ago> The biggest problem is any string you pass as an argument to the fmt functions is moved onto the heap FWIW, that's not quite correct. For example, a string literal passed as a fmt argument won't be moved to the heap. The upcoming Go 1.25 release has some related improvements that help strings in more cases. See for example https://go.dev/cl/649079 https://go.dev/cl/649079.
- fsmv 1y agoYeah I just saw in the bug they're finally making progress on fixing this, exciting! I edited in the link if you didn't see.
- coxley 1y ago> because interface{} is always counted as escaped from the stack Not quite - if the function accepting interface{} can be inlined (and other heuristics are groovy), then it won't escape. Trivial example but it applies to real-world programs: > cat main.go package main import "github.com/google/uuid" func main() { _ = foo(uuid.NewString()) } func foo(s any) string { switch s := s.(type) { case string: _ = "foo:" + s } return "" } # Build with escape analysis > go build -gcflags="-m=2" main.go # command-line-arguments ./main.go:9:6: can inline foo with cost 13 as: func(any) string { switch statement; return "" } ./main.go:5:6: can inline main with cost 77 as: func() { _ = foo(uuid.NewString()) } ./main.go:6:9: inlining call to foo ./main.go:6:24: uuid.NewString() does not escape ./main.go:6:9: "foo:" + s does not escape ./main.go:9:10: s does not escape ./main.go:12:14: "foo:" + s does not escape
- tapirl 1y agoThat is a general rule. Yours is a special case.