cmd/compile: inlining confuses escape analysis with interface{} params #53465
Labels
NeedsInvestigation
Someone must examine and confirm this is a valid issue and not a duplicate of an existing one.
Performance
Milestone
Take a look at https://go.dev/play/p/mPqA0RaybuQ.
On
go version devel go1.19-9068c6844d Thu Jun 16 21:58:40 2022 +0000 linux/amd64
I get the following benchmark results:First, note that both debugf functions are inlined:
And, in the
true
sub-benchmarks where debug logging is enabled and we actually callSprintf
, we can see three allocations - two corresponding to the twointerface{}
parameters, as thestring
andint
variables escape to the heap via the interface, and one for the actual call toSprintf
constructing a string.So far so good. However, when debug logging is disabled, I want to avoid those allocations, because this debug logging happens in a tight loop that runs millions of times in a program, so I want to avoid millions of allocations made in a very short amount of time.
This works fine for the "manually inlined" case where I wrap the call to Debugf with a conditional. Note the zero allocations on
InlinedDebugf/false
. However, that means that every time I want to use Debugf (a dozen times in said program), I need three lines rather than one, and it's pretty repetitive and verbose.One good alternative is to move the conditional inside the Debugf function - and since it's still inlined, it should be the same result. However,
ConditionalDebugf/false
allocates twice, presumably because the two arguments do still allocate, as if I was actually callingSprintf
when in fact I am not.It seems to me like the two benchmarks should behave the same; the compiler's escape analysis and inliner should work well enough together to detect this scenario.
Note that my real use case involves
log.Printf
, which is a no-op when one has calledlog.SetOutput(io.Discard)
. The benchmark above is a simplification which still reproduces the same problem.The text was updated successfully, but these errors were encountered: