MessagePack Formatter: Cache Span tag keys in UTF8#1482
Conversation
78e3c99 to
2871d9d
Compare
andrewlock
left a comment
There was a problem hiding this comment.
Nice 👍 I'm kind of surprised there's no change in the allocations though, I guess MessagePackBinary.WriteString is caching the byte[] behind the scene?
No, is not caching, is writing directly to the actual buffer... https://github.com/DataDog/dd-trace-dotnet/blob/master/src/Datadog.Trace/Vendors/MessagePack/MessagePackBinary.cs#L1715 Also, I do think there is a change on allocations, can be seen in |
| private static byte[] _traceIdBytes = StringEncoding.UTF8.GetBytes("trace_id"); | ||
| private static byte[] _spanIdBytes = StringEncoding.UTF8.GetBytes("span_id"); | ||
| private static byte[] _nameBytes = StringEncoding.UTF8.GetBytes("name"); | ||
| private static byte[] _resourceBytes = StringEncoding.UTF8.GetBytes("resource"); | ||
| private static byte[] _serviceBytes = StringEncoding.UTF8.GetBytes("service"); | ||
| private static byte[] _typeBytes = StringEncoding.UTF8.GetBytes("type"); | ||
| private static byte[] _startBytes = StringEncoding.UTF8.GetBytes("start"); | ||
| private static byte[] _durationBytes = StringEncoding.UTF8.GetBytes("duration"); | ||
| private static byte[] _parentIdBytes = StringEncoding.UTF8.GetBytes("parent_id"); | ||
| private static byte[] _errorBytes = StringEncoding.UTF8.GetBytes("error"); |
There was a problem hiding this comment.
Should we make these not static? Did we benchmark in .NET Framework loading Datadog.Trace.dll domain-neutral?
Access to static data and methods is slower for domain-neutral assemblies because of the need to isolate assemblies. Each application domain that accesses the assembly must have a separate copy of the static data, to prevent references to objects in static fields from crossing domain boundaries. As a result, the runtime contains additional logic to direct a caller to the appropriate copy of the static data or method. This extra logic slows down the call.
There was a problem hiding this comment.
Thanks for this, as we talked, I'll run some benchmarks for curiosity about the performance impact on domain neutral assemblies. But it doesn't make any harm to change it to instance fields in the SpanMessagePackFormatter file if we double check we use a single instance. I will do a PR for that.
Old:
// * Summary *
BenchmarkDotNet=v0.12.1, OS=Windows 10.0.19042
Intel Xeon CPU E5-2673 v3 2.40GHz, 1 CPU, 4 logical and 2 physical cores
.NET Core SDK=5.0.201
[Host] : .NET Core 3.1.7 (CoreCLR 4.700.20.36602, CoreFX 4.700.20.37001), X64 RyuJIT
Job-WEIHTL : .NET Framework 4.8 (4.8.4341.0), X64 RyuJIT
Job-VTKECX : .NET Core 3.1.7 (CoreCLR 4.700.20.36602, CoreFX 4.700.20.37001), X64 RyuJIT
IterationTime=1.5000 s
New:
// * Summary *
BenchmarkDotNet=v0.12.1, OS=Windows 10.0.19042
Intel Xeon CPU E5-2673 v3 2.40GHz, 1 CPU, 4 logical and 2 physical cores
.NET Core SDK=5.0.201
[Host] : .NET Core 3.1.7 (CoreCLR 4.700.20.36602, CoreFX 4.700.20.37001), X64 RyuJIT
Job-GAZNKL : .NET Framework 4.8 (4.8.4341.0), X64 RyuJIT
Job-NQGFHJ : .NET Core 3.1.7 (CoreCLR 4.700.20.36602, CoreFX 4.700.20.37001), X64 RyuJIT
IterationTime=1.5000 s
Diff:
@DataDog/apm-dotnet