Low hanging fruit startup optimization#3195
Conversation
This comment has been minimized.
This comment has been minimized.
| // this way we avoid the reflection invoke call. | ||
| if (assembly.GetType(loaderHelperTypeName, throwOnError: false) is { } loaderHelperType) | ||
| { | ||
| Activator.CreateInstance(loaderHelperType); |
There was a problem hiding this comment.
Are you sure Activator.CreateInstance is faster than invoking a method through reflection? 🤔
There was a problem hiding this comment.
There was a problem hiding this comment.
Is not exactly the same case, but very similar, and also one thing to take in consideration is that on startup time in the tracer we have NGEN disabled and instrumenting through the JITCompilationStart to inject the loader. So less internal calls the better. And I think calling by reflection will result in more checks and internals calls, althought I'm not 100% sure of this.
There was a problem hiding this comment.
BenchmarkDotNet=v0.12.1, OS=Windows 10.0.22000
AMD Ryzen 9 5950X, 1 CPU, 32 logical and 16 physical cores
.NET Core SDK=7.0.100-preview.7.22377.5
[Host] : .NET Core 3.1.28 (CoreCLR 4.700.22.36202, CoreFX 4.700.22.36301), X64 RyuJIT
DefaultJob : .NET Core 3.1.28 (CoreCLR 4.700.22.36202, CoreFX 4.700.22.36301), X64 RyuJIT
| Method | Mean | Error | StdDev | Median | Gen 0 | Gen 1 | Gen 2 | Allocated |
|-------------------------- |---------:|---------:|---------:|---------:|-------:|------:|------:|----------:|
| ReflectionInvokeBenchmark | 74.25 ns | 0.646 ns | 0.605 ns | 74.37 ns | - | - | - | - |
| ActivatorBenchmark | 30.30 ns | 0.760 ns | 2.194 ns | 30.90 ns | 0.0000 | - | - | 24 B |
AMD Ryzen 9 5950X, 1 CPU, 32 logical and 16 physical cores
[Host] : .NET Framework 4.8 (4.8.4515.0), X64 RyuJIT
DefaultJob : .NET Framework 4.8 (4.8.4515.0), X64 RyuJIT
| Method | Mean | Error | StdDev | Gen 0 | Gen 1 | Gen 2 | Allocated |
|-------------------------- |----------:|---------:|---------:|-------:|------:|------:|----------:|
| ReflectionInvokeBenchmark | 103.12 ns | 0.835 ns | 0.740 ns | - | - | - | - |
| ActivatorBenchmark | 56.75 ns | 0.299 ns | 0.280 ns | 0.0038 | - | - | 24 B |
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
andrewlock
left a comment
There was a problem hiding this comment.
LGTM, but what happened to those public API tests? 😬
| namespace Datadog.Trace | ||
| { | ||
| public sealed class AgentProcessManagerLoader | ||
| { | ||
| public AgentProcessManagerLoader() { } | ||
| } | ||
| public static class CorrelationIdentifier |
There was a problem hiding this comment.
Um.... :wat:
I guess we need to sort the namespaces in here or something 😬
There was a problem hiding this comment.
I didn't do anything, just updated the snapshot I guess it is because the sorting indeed.
Benchmarks Report 🐌Benchmarks for #3195 compared to master:
The following thresholds were used for comparing the benchmark speeds:
Allocation changes below 0.5% are ignored. Benchmark detailsBenchmarks.Trace.AgentWriterBenchmark - Same speed ✔️ Same allocations ✔️Raw results
Benchmarks.Trace.AppSecBodyBenchmark - Same speed ✔️ Same allocations ✔️Raw results
Benchmarks.Trace.AspNetCoreBenchmark - Unknown 🤷 Same allocations ✔️Raw results
Benchmarks.Trace.DbCommandBenchmark - Same speed ✔️ Same allocations ✔️Raw results
Benchmarks.Trace.ElasticsearchBenchmark - Same speed ✔️ Same allocations ✔️Raw results
Benchmarks.Trace.GraphQLBenchmark - Same speed ✔️ Same allocations ✔️Raw results
Benchmarks.Trace.HttpClientBenchmark - Same speed ✔️ Same allocations ✔️Raw results
Benchmarks.Trace.ILoggerBenchmark - Same speed ✔️ Same allocations ✔️Raw results
Benchmarks.Trace.Log4netBenchmark - Same speed ✔️ Same allocations ✔️Raw results
Benchmarks.Trace.NLogBenchmark - Same speed ✔️ Same allocations ✔️Raw results
Benchmarks.Trace.RedisBenchmark - Same speed ✔️ Same allocations ✔️Raw results
Benchmarks.Trace.SerilogBenchmark - Same speed ✔️ Same allocations ✔️Raw results
Benchmarks.Trace.SpanBenchmark - Same speed ✔️ Same allocations ✔️Raw results
Benchmarks.Trace.TraceAnnotationsBenchmark - Same speed ✔️ Same allocations ✔️Raw results
|
Code Coverage Report 📊✔️ Merging #3195 into master will will increase line coverage by
View the full report for further details: Datadog.Trace Breakdown ✔️
The following classes have significant coverage changes.
The following classes were added in #3195:
View the full reports for further details: |
Summary of changes
This PR contains a simple optimization to avoid the reflection
Invokecall at startup.