Skip to content
This repository was archived by the owner on Jan 23, 2023. It is now read-only.

Conversation

@Wraith2
Copy link
Contributor

@Wraith2 Wraith2 commented Nov 18, 2018

When using trusted authentication with connection pooling profiling has shown that getting the connection from the pool and getting the security information from the unmanaged library are hot paths.

This PR slightly rearranges the code in the connection pool key identification code to be more efficient about use of the user SecurityIdentifier object fetching it only once because it is expensive and calling ToString() directly instead of using Value because Value will make an unneeded ToUpperInvariant() call.
It also changes the allocation of SSPI buffers to use the ArrayPool, in testing the sspi buffers were being requested at 55K each time which caused a lot of memory churn.

Combined with the changes in #33579 this should allow connections to be retrieved ~20% faster allowing better short frequent query throughput. I'm still having trouble with benching but the profile run output is reasonable, all tests pass and the changes are very small.

after

/CC @keeratsingh, @afsanehr, @saurabh500, @divega

change SSPI login buffers to arraypool allocations
@karelz
Copy link
Member

karelz commented Nov 21, 2018

@karelz
Copy link
Member

karelz commented Nov 21, 2018

@dotnet-bot test this please

@Wraith2
Copy link
Contributor Author

Wraith2 commented Nov 22, 2018

Yes it is related. There's a very peculiar case in managed only mode (so not reachable on windows desktop) where it reassigns the buffer about 4 calls below where it's allocated. It could just have returned a 0 length as far as I can see but I really don't want to try and rework the state object interface at this point so I've worked around by keeping a separate reference to the rental and releasing that.

@Wraith2
Copy link
Contributor Author

Wraith2 commented Nov 22, 2018

@dotnet-bot test Linux arm64 release please

@Wraith2
Copy link
Contributor Author

Wraith2 commented Nov 23, 2018

@dotnet-bot test this please

@Wraith2
Copy link
Contributor Author

Wraith2 commented Nov 28, 2018

@dotnet-bot test UWP CoreCLR x64 Debug Build please

string sidString = identity.User.Value;
SecurityIdentifier user = identity.User;
bool isNetwork = user.IsWellKnown(WellKnownSidType.NetworkSid);
string sidString = user.ToString();
Copy link
Contributor

@saurabh500 saurabh500 Dec 14, 2018

Choose a reason for hiding this comment

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

Why use ToString()? The docs mention that Value provides the upper case value of SID and ToString() has no such guarantees.
It makes sense to leave this part of assigning sidString as is.

Copy link
Contributor

Choose a reason for hiding this comment

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

For the sake on consistency, I think it makes more sense to use the Value instead of ToString()

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I rewrote the code for ToString() to be faster in #33579 In fact it is guaranteed that the ToString() return value has an uppercase S in it because it's a literal.

Calling ToUpperCase() on it is a waste of time. There is no need for the returned value to be uppercased only that it be consistent with every call, the only use is as part of the pool key so case is irrelevant. I judged it better not to waste time making a call that can be proven to have no effect.

Copy link
Contributor

@saurabh500 saurabh500 Dec 14, 2018

Choose a reason for hiding this comment

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

The part that is concerning to me is that knowing that ToString() implementation has an uppercase S is an internal detail vs there is an API called .Value which guarantees upper case string.

In terms of API consistency, if this code is to execute on another framework which doesn't have the same guarantees of internals, that you are describing, then this connection pool code may fall apart.

You improved the performance of ToString(), which means that there should be an overall improvement with .Value retrieval as well on .Net Core

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It doesn't matter about the case though because we only use the value as part of the pool key, upper or mixed is irrelevant as long as it's the same every time we ask for it from SecurityIdentifier.

I can change it back if you really want and we won't lose much it's a really tiny improvement compared to the other changes, it just bothers me to do something I know is worthless.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done, the perf change isn't worth worrying about.

@saurabh500 saurabh500 merged commit 9b6618f into dotnet:master Dec 18, 2018
@Wraith2 Wraith2 deleted the sqlconnperf branch December 20, 2018 00:56
@karelz karelz added this to the 3.0 milestone Dec 21, 2018
picenka21 pushed a commit to picenka21/runtime that referenced this pull request Feb 18, 2022
* change pool to fetch user object only once and use direct tostirng
change SSPI login buffers to arraypool allocations

* change rental to keep track of rented array in case the caller reassigns

* address feedback


Commit migrated from dotnet/corefx@9b6618f
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

7 participants