Skip to content

Conversation

@MihaZupan
Copy link
Member

@MihaZupan MihaZupan commented May 7, 2021

Building on top of #51822 and #52092.

  • Reduced the size of EventWrittenEventArgs for the common case

    • As a minimum, events need the EventSource, EventId, TimeStamp and Payload.
    • Moved the rest to a MoreInfo class that's allocated only if more parameters are set:
    • ActivityId, RelatedActivityId, Tags, Opcode, Level, Keywords, ThreadId, PayloadNames, EventName, Message
  • Stored ParameterNames on EventMetadata instead of EventWrittenEventArgs

  • Avoided duplication around TraceLoggingEventTypes 293538e

Benchmarks.cs

Method Toolchain Mean Error Ratio Gen 0 Allocated
WriteEventNoParams base 74.98 ns 0.635 ns 1.00 0.0440 184 B
WriteEventNoParams after 52092 (current main) 56.56 ns 0.447 ns 0.75 0.0325 136 B
WriteEventNoParams new 49.36 ns 0.430 ns 0.66 0.0134 56 B
WriteHttpRequestStart base 809.63 ns 5.650 ns 1.00 0.1068 448 B
WriteHttpRequestStart after 52092 (current main) 206.04 ns 2.987 ns 0.25 0.1070 448 B
WriteHttpRequestStart new 186.86 ns 1.385 ns 0.23 0.0880 368 B
FullYarpRequest base 5,913.87 ns 43.604 ns 1.00 1.2054 5048 B
FullYarpRequest after 52092 (current main) 1,973.14 ns 7.223 ns 0.33 1.1368 4761 B
FullYarpRequest new 1,764.72 ns 10.423 ns 0.30 0.7744 3241 B

Should be all from me around EventSource for a while.

PR adding a subset of these benchmarks to the performance repo: dotnet/performance#1800

@MihaZupan MihaZupan added this to the 6.0.0 milestone May 7, 2021
@MihaZupan MihaZupan requested review from josalem, noahfalk and sywhang May 7, 2021 17:31
@ghost
Copy link

ghost commented May 7, 2021

Tagging subscribers to this area: @tarekgh, @tommcdon, @pjanotti
See info in area-owners.md if you want to be subscribed.

Issue Details

Building on top of #51822 and #52092.

  • Reduced the size of EventWrittenEventArgs for the common case

    • As a minimum, events need the EventSource, EventId, TimeStamp and Payload.
    • Moved the rest to a MoreInfo class that's allocated only if more parameters are set:
    • ActivityId, RelatedActivityId, Tags, Opcode, Level, Keywords, ThreadId, PayloadNames, EventName, Message
  • Stored ParameterNames on EventMetadata instead of EventWrittenEventArgs

  • Avoided duplication around TraceLoggingEventTypes 293538e

Benchmarks.cs

Method Toolchain Mean Error Ratio Gen 0 Allocated
WriteEventNoParams base 74.98 ns 0.635 ns 1.00 0.0440 184 B
WriteEventNoParams after 52092 (current main) 56.56 ns 0.447 ns 0.75 0.0325 136 B
WriteEventNoParams new 49.36 ns 0.430 ns 0.66 0.0134 56 B
WriteHttpRequestStart base 809.63 ns 5.650 ns 1.00 0.1068 448 B
WriteHttpRequestStart after 52092 (current main) 206.04 ns 2.987 ns 0.25 0.1070 448 B
WriteHttpRequestStart new 186.86 ns 1.385 ns 0.23 0.0880 368 B
FullYarpRequest base 5,913.87 ns 43.604 ns 1.00 1.2054 5048 B
FullYarpRequest after 52092 (current main) 1,973.14 ns 7.223 ns 0.33 1.1368 4761 B
FullYarpRequest new 1,764.72 ns 10.423 ns 0.30 0.7744 3241 B

Should be all from me around EventSource for a while. I'll put up a PR to get some of these benchmarks in the performance repo.

Author: MihaZupan
Assignees: -
Labels:

area-System.Diagnostics.Tracing

Milestone: 6.0.0
{
#if !ES_BUILD_STANDALONE
[RequiresUnreferencedCode(EventSourceRequiresUnreferenceMessage)]
#endif
Copy link
Member Author

@MihaZupan MihaZupan May 7, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@LakshanF is adding this attribute sufficient here?

(TraceLoggingEventTypes initialization & synchronization was moved into this getter in 293538e)

{
Guid activityId = m_activityId;
if (activityId == Guid.Empty)
if (_moreInfo is MoreEventInfo moreInfo && moreInfo.ActivityId != Guid.Empty)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What happens to performance if you add TplEventSource keyword=0x80 to the trace which enables activity tracking? Even if the Yarp telemetry doesn't enable the keyword there is a decent (and growing) chance that some other EventSource session will enable it and the effects are global. I'm worried that it may be a common scenario that causes EventListener to fall off the fast path in which case it may be better to add ActivityId (but not RelatedActivityId) to the default field set.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How common is it for users to enable activity tracking while using in-process EventListeners as well?

The perf wouldn't be much worse in that case (an extra object allocation). If you believe using EventListener and 0x80 at the same time is common enough I can move the ActivityId off of ExtraInfo as you suggested.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My guess is that the usage would be uncorrelated, but if both are independently common enough then there could still be significant overlap - this is just educated guessing on my part. If the perf consequence isn't that meaningful then there is no need to worry, but I assumed you wouldn't have done the optimization at all if it didn't make a difference.

Copy link
Member Author

@MihaZupan MihaZupan May 11, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Method Toolchain Mean Error Ratio Gen 0 Allocated
WriteEventNoParams OnExtraInfo 55.46 ns 1.125 ns 1.00 0.0134 56 B
WriteEventNoParams OnBaseObject 53.52 ns 0.420 ns 0.96 0.0172 72 B
WriteEventNoParams_ActivityId OnExtraInfo 84.18 ns 0.631 ns 1.00 0.0401 168 B
WriteEventNoParams_ActivityId OnBaseObject 77.48 ns 0.679 ns 0.92 0.0172 72 B
FullYarpRequest OnExtraInfo 1,939.21 ns 38.206 ns 1.00 0.7744 3241 B
FullYarpRequest OnBaseObject 1,948.20 ns 20.337 ns 1.00 0.8469 3545 B
FullYarpRequest_ActivityId OnExtraInfo 5,101.87 ns 85.053 ns 1.00 2.4490 10266 B
FullYarpRequest_ActivityId OnBaseObject 4,558.92 ns 31.574 ns 0.89 1.6022 6713 B

Moved it back onto the base object.
Looks like a measurable improvement for the case when ActivityId is accessed while not really affecting other cases.

@noahfalk
Copy link
Member

Copy link
Member

@noahfalk noahfalk left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looked good to me though I'd like one off @josalem, @sywhang, @davmason to take a look as well.

Copy link
Contributor

@josalem josalem left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I read this one when it first went up, but apparently forgot to hit the approve button! Thanks!

Copy link
Contributor

@sywhang sywhang left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@MihaZupan
Copy link
Member Author

Failure: #11063

@MihaZupan MihaZupan merged commit 2e618ff into dotnet:main May 12, 2021
@ghost ghost locked as resolved and limited conversation to collaborators Jun 11, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.