NoOpTracer still sets up attributes when calling Span.updateAttributes
When you call Span.updateAttributes(_:) on a NoOpSpan the included closure shouldn't be called. This is the cause of unexpected allocations when the tracer has been set to NoOp.
Is adding the function to the protocol a breaking change if you provide a default implementation?
Not calling the closure could be considered a breaking change I suppose given people might do other stuff inside that closure.
Ideally SpanAttributes would be an associatedtype and the NoOpSpan would have its own version that didn't do anything, but I think that ship may have sailed.
Is adding the function to the protocol a breaking change if you provide a default implementation?
This is ok, we can do this.
Not calling the closure could be considered a breaking change I suppose given people might do other stuff inside that closure.
Kinda... but I'm willing to bet on it being fair enough to not call the closure at all on a NoOpSpan.
It's a goal for us to shave off any wasteful allocations etc, so I's support fixing this
I'm a bit iffy on not calling the user-provided closure. The doc comment on the method doesn't mention that it wouldn't be called under some circumstances and it can break existing invariants in people's code.
My lean would be to still call it, and give it transient span attributes which the method then throws away.
This should give enough knowledge to the compiler to see what's happening and hopefully optimize all of it away once we have better cross-module optimization.