In trying to debug a very rare bug in tests I’m writing, I decided to add a very homebrew tracing mechanism to my code. Basically I have
#tracer?: Array<string>;
myclass.setTracer(tracer?: Array<string>) {
this.#tracer = tracer;
}
#trace(msg: string) {
if (this.#tracer) {
this.#tracer.push(msg);
}
I can then add a call to setTracer(someArrayOfString)
and pepper my code with
this.#trace("my message");
and if I fail, print out the trace I have in someArrayOfStrings to try and figure out what went wrong.
However, this would seemingly have a performance hit, especially if I’m creating unique strings (i.e. interpolating variables).
I figure, I could probably do something like to avoid the string creation (though maybe I’m wrong about the optimizations)
(this.#tracer !== undefined) && this.#tracer.push(msg);
but I find peppering my code with that instead of the the "cleaner" this.#trace() call (that effectively does the same logical thing, but only after string has been created).
Is it possible to improve this? I assume others have thought of this, and perhaps have better solutions that I’d be willing to implement (just don’t know them).
any recommendations would be appreciated.
2
Answers
Preface: Rather than doing something bespoke, you might consider looking into existing tools for doing tracing/instrumention. But taking the question as asked:
You can avoid the string interpolation by making the
#trace
method, itself, the thing that’s eitherundefined
or a function:Then use optional chaining on the actual calls:
If that statement executes when
this.#trace
isundefined
, the string interpolation is never performed, because the statement short-circuits as of the optional chaining (.?
). That’s specified behavior.In JavaScript you’d have the concern that you could easily forget the
.?
, but not in TypeScript; TypeScript will show you an error if you forget it, thanks to#trace
potentially beingundefined
.If you want to prove that the interpolation doesn’t happen to yourself, you can do one with a side-effect:
Example in JavaScript:
I recommend using the empty function instead of any check for
#trace
or#tracer
.For example:
Below is my test code, assuming a production environment where you don’t use
setTracer
:Using an empty function completely beats the other contenders!