Optimise StackTraceSnippet.Get #605
Merged
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
TL;DR: Cache the names of
System.Reflection.Assembly
andSystem.Reflection.Module
instances in a static dictionary as they are non-trivially recomputed on every read of the property. This reduces allocations by ~70% and doubles speed when instantiatingCustomTiming
with stack traces (the default behaviour).Instantiating
CustomTiming
with 'normal' parameters allocated a surprisingly large amount in the benchmarks. A chunk of it is from callingnew StackTrace().GetFrames();
which I don't think we can do anything about in a reasonable way.. but most was from reflection, which is almost completely mitigated by these changes.The problem is that
Assembly.GetName().Name
andModule.Name
don't persist the resulting value. You can see that here and here forAssembly
, and here forModule
. I think it should be safe to just cache those results in a shared static dict. As far as I'm aware, this shouldn't get too bloated. If there is some chance of insane numbers of assemblies/modules, we could have it auto-clear at a certain number of items.After these changes, ~93% of the remaining allocations in the
CustomTiming
ctor benchmark are fromnew StackTrace().GetFrames();
.Benchmarks!
Before:
After: