Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

More EventListener overhead reductions#52092

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to ourterms of service andprivacy statement. We’ll occasionally send you account related emails.

Already on GitHub?Sign in to your account

Merged
MihaZupan merged 7 commits intodotnet:mainfromMihaZupan:event-listener-2
May 7, 2021

Conversation

@MihaZupan
Copy link
Member

@MihaZupanMihaZupan commentedApr 30, 2021
edited
Loading

This PR builds on top of#51822, focusing entirely onDecodeObject speed.

I special-casedAllParametersAreString andAllParametersAreInt32 (as that seems to be by far most common).
Make use ofType.GetTypeCode inDecodeObject to speed up all the other cases.

Opening this PR to get some CI coverage as I added debug asserts around the user-suppliedEventData.Size.

Benchmarks.cs

MethodToolchainMeanErrorRatioAllocated
WriteEventNoParamsbase72.91 ns0.036 ns1.00184 B
WriteEventNoParamsPR5182256.61 ns0.028 ns0.78136 B
WriteEventNoParamsnew55.98 ns0.018 ns0.77136 B
3 int32 args
WriteEventIntParamsbase182.35 ns0.067 ns1.00280 B
WriteEventIntParamsPR51822128.17 ns0.039 ns0.70280 B
WriteEventIntParamsnew95.47 ns0.098 ns0.52280 B
3 strings
WriteEventStringParamsbase488.94 ns0.243 ns1.00312 B
WriteEventStringParamsPR51822401.55 ns0.210 ns0.82312 B
WriteEventStringParamsnew114.08 ns0.055 ns0.23312 B
3 enums, 1 being int64
WriteEventEnumParamsbase571.13 ns0.905 ns1.00280 B
WriteEventEnumParamsPR51822478.64 ns0.309 ns0.84280 B
WriteEventEnumParamsnew123.86 ns0.018 ns0.22280 B
3 enums, all <= int32
WriteEventSmallEnumParamsbase555.12 ns0.223 ns1.00280 B
WriteEventSmallEnumParamsPR51822467.77 ns0.324 ns0.84280 B
WriteEventSmallEnumParamsnew87.88 ns0.218 ns0.16280 B
A single HttpTelemetry RequestStart event
WriteHttpRequestStartbase834.12 ns0.420 ns1.00448 B
WriteHttpRequestStartPR51822666.90 ns0.640 ns0.80448 B
WriteHttpRequestStartnew237.61 ns0.213 ns0.28448 B
19 events - avg overhead
FullYarpRequestbase5,748.42 ns2.780 ns1.005048 B
FullYarpRequestPR518224,737.74 ns2.637 ns0.824760 B
FullYarpRequestnew2,007.78 ns1.156 ns0.354761 B

I'd assume this is about as far as we can get with the current API shape (args+payload+boxing+strings).

Wraith2 reacted with thumbs up emoji
@ghost
Copy link

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

Issue Details

This PR builds on top of#51822, focusing entirely onDecodeObject speed.

I special-casedAllParametersAreString andAllParametersAreInt32 (as that seems to be by far most common).
Since we're in CoreLib, we can make use ofGetCorElementType inDecodeObject to speed up all the other cases.

Opening this PR to get some CI coverage as I added debug asserts around the user-suppliedEventData.Size.

Benchmarks.cs

MethodToolchainMeanErrorRatioAllocated
WriteEventNoParamsbase77.36 ns0.599 ns1.00184 B
WriteEventNoParamsPR5182263.90 ns1.219 ns0.83136 B
WriteEventNoParamsnew58.89 ns0.434 ns0.76136 B
3 int32 args
WriteEventIntParamsbase259.60 ns4.737 ns1.00280 B
WriteEventIntParamsPR51822127.87 ns1.163 ns0.49280 B
WriteEventIntParamsnew102.47 ns0.853 ns0.39280 B
3 strings
WriteEventStringParamsbase520.92 ns7.796 ns1.00312 B
WriteEventStringParamsPR51822449.73 ns8.842 ns0.86312 B
WriteEventStringParamsnew128.39 ns2.499 ns0.25312 B
3 enums, 1 being int64
WriteEventEnumParamsbase639.98 ns5.292 ns1.00280 B
WriteEventEnumParamsPR51822490.84 ns2.366 ns0.77280 B
WriteEventEnumParamsnew195.63 ns1.246 ns0.31280 B
3 enums, all <= int32
WriteEventSmallEnumParamsbase589.55 ns6.061 ns1.00280 B
WriteEventSmallEnumParamsPR51822484.31 ns1.814 ns0.82280 B
WriteEventSmallEnumParamsnew93.74 ns1.568 ns0.16280 B
A single HttpTelemetry RequestStart event
WriteHttpRequestStartbase868.10 ns4.009 ns1.00448 B
WriteHttpRequestStartPR51822700.26 ns6.704 ns0.81448 B
WriteHttpRequestStartnew287.17 ns5.302 ns0.33448 B
19 events - avg overhead
FullYarpRequestbase6.198 us0.076 us1.004.93 KB
FullYarpRequestPR518224.900 us0.056 us0.794.65 KB
FullYarpRequestnew2.163 us0.012 us0.354.65 KB

I'd assume this is about as far as we can get with the current API shape (args+payload+boxing+strings).

Author:MihaZupan
Assignees:-
Labels:

area-System.Diagnostics.Tracing

Milestone:6.0.0

TypeCodetypeCode=Type.GetTypeCode(dataType);
intsize=data->Size;

if(size==4)
Copy link
Contributor

Choose a reason for hiding this comment

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

Wouldn't be a simple switch over typeCode instead of multiple levels of nested ifs faster?

Copy link
MemberAuthor

Choose a reason for hiding this comment

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

They don't always match up here.
For enums, EventSource treats them asint32, butType.GetTypeCode(dataType) will resolve the underlying type.
That is why the[SByte, Int32] range is being checked undersize == 4 (and read as anint*), but then also checked outside thesize == 4 case.

Copy link
Contributor

Choose a reason for hiding this comment

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

Unless you'd like to optimize for non-int enums it still seems to me that the switch would be better option

Copy link
MemberAuthor

Choose a reason for hiding this comment

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

In that case you would have duplication like

caseTypeCode.Byte:if(dataType.IsEnum){Debug.Assert(size==4);return*(int*)dataPointer;}else{Debug.Assert(size==1);return*(byte*)dataPointer;}caseTypeCode.SByte:if(dataType.IsEnum){Debug.Assert(size==4);return*(int*)dataPointer;}else{Debug.Assert(size==1);return*(sbyte*)dataPointer;}// ...

For byte, sbyte, short, ushort, int.

I can measure, but I doubt changing to a switch would be faster here.

@MihaZupan
Copy link
MemberAuthor

MihaZupan commentedMay 3, 2021
edited
Loading

Updated the benchmarks above with the latest changes

@tommcdon
Copy link
Member

@sywhang

// null in the string.
#ifDEBUG
Debug.Assert(data->Size%2==0,"String size should be even");
for(inti=0;i<data->Size/2-1;i++)Debug.Assert(*((char*)dataPointer+i)!=0,"String may not contain null chars");
Copy link
Contributor

@sywhangsywhangMay 3, 2021
edited
Loading

Choose a reason for hiding this comment

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

FYI@josalem: this change can be related to#52025 for EventPipe/ETW

Copy link
Contributor

Choose a reason for hiding this comment

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

Yup. There's currently nothing stopping users from putting a string with embedded nulls intoEventSource.

Copy link
Member

@noahfalknoahfalk left a comment

Choose a reason for hiding this comment

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

LGTM though it would be good if at least one of@sywhang,@davmason or@josalem can confirm as well. Thanks for the great perf wins!

else
{
for(inti=0; i<args.Length; i++,data++)
{
Copy link
Member

Choose a reason for hiding this comment

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

There might be a little more perf to gain if the for loop is inside the method rather than outside of it. I'm guessing DecodeObject() isn't being inlined right now and making the loop body opaque inside the method doesn't give the JIT as much visbility to optimize. There is probably also a tiny overhead in repeated execution of the DecodeObject prolog/epilog.

MihaZupan and josalem reacted with thumbs up emoji
Copy link
MemberAuthor

Choose a reason for hiding this comment

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

ChangedDecodeObject toDecodeObjects. Control flow is a bit messier (yay for goto), but it does give us a few extra %.

Roughly ~10% improvement forWriteHttpRequestStart.

josalem reacted with hooray emoji
Copy link
Member

Choose a reason for hiding this comment

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

Oh nice, ~10% is even more than I would have guessed : )

Copy link
Contributor

@josalemjosalem left a comment

Choose a reason for hiding this comment

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

Thanks@MihaZupan!

@MihaZupan
Copy link
MemberAuthor

MethodToolchainMeanErrorRatio
WriteEventEnumParamsDecodeObject124.07 ns0.063 ns1.00
WriteEventEnumParamsDecodeObjects119.49 ns0.409 ns0.96
WriteHttpRequestStartDecodeObject236.24 ns1.064 ns1.00
WriteHttpRequestStartDecodeObjects207.29 ns0.646 ns0.88
FullYarpRequestDecodeObject2,033.16 ns8.476 ns1.00
FullYarpRequestDecodeObjects1,995.76 ns5.244 ns0.98

@MihaZupan
Copy link
MemberAuthor

Failure unrelated:#51819

Sign up for freeto subscribe to this conversation on GitHub. Already have an account?Sign in.

Reviewers

@marek-safarmarek-safarmarek-safar left review comments

@noahfalknoahfalknoahfalk approved these changes

@jkotasjkotasjkotas left review comments

+2 more reviewers

@josalemjosalemjosalem approved these changes

@sywhangsywhangsywhang approved these changes

Reviewers whose approvals may not affect merge requirements

Assignees

No one assigned

Projects

None yet

Milestone

6.0.0

Development

Successfully merging this pull request may close these issues.

7 participants

@MihaZupan@tommcdon@marek-safar@noahfalk@jkotas@josalem@sywhang

[8]ページ先頭

©2009-2025 Movatter.jp