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

SqlClient reduce memory use for repeated ExecuteNonQueryAsync#36108

Closed
Wraith2 wants to merge 11 commits into
dotnet:masterfrom
Wraith2:sqlperf-asyncexecute
Closed

SqlClient reduce memory use for repeated ExecuteNonQueryAsync#36108
Wraith2 wants to merge 11 commits into
dotnet:masterfrom
Wraith2:sqlperf-asyncexecute

Conversation

@Wraith2

@Wraith2 Wraith2 commented Mar 17, 2019

Copy link
Copy Markdown
Contributor

When using SqlCommand.ExecuteNonQueryAsync delegates for the async continuations and convertion from BeginEnd to Task are allocated on each call. This PR introduces a new class called ExecuteAsyncHelper which allows lazy creation and caching of those delegates for each connection object. This is of benefit when using the same command object to call ExecuteNonQueryAsync multiple times but has a very minor (a single wrapping object) degradation on single call per command, in practice I expect this additional memory to get lost in the noise and I think I've made enough improvements in other PR's to have a little space to work with.

Continuing the theme of reducing repeated delegate creation I have added some a cached delegate and context objects to SqlReferenceCollection which is used when validating that the connection is in a state allowing execution, this will affect all kinds of query, the general pattern used is one I've found elsewhere in the corefx codebase:

    FindLiveReaderContext context = Interlocked.Exchange(ref cachedFindLiveReaderContext, null) ?? new FindLiveReaderContext();
    context.Setup(command);
    SqlDataReader retval = FindItem(DataReaderTag, context.Func);
    context.Clear();
    Interlocked.CompareExchange(ref cachedFindLiveReaderContext, context, null);

using interlocked to try and re-use a single item per collection if possible and falling back to the previous allocating behaviour in the case where it isn't available. This should allow low contention scenarios to be low allocation and ramp up to meet high contention needs without bottlenecking.

The performance improvements are modest:

Method Mean Error StdDev Gen 0/1k Op Gen 1/1k Op Gen 2/1k Op Allocated Memory/Op
AsyncFloat32 master 212.9 ms 1.896 ms 1.681 ms - - - 1.95 KB
AsyncFloat32 branch 212.0 ms 1.479 ms 1.235 ms - - - 1.47 KB

This is mostly because the dominating allocations are unavoidable task machinery or waiting another PR SqlParameter cleanup.
asyncnonquery-dottrace.

All the usual functional and manual tests pass.
/cc @afsanehr @tarikulsabbir, @Gary-Zh , @David-Engel

@AfsanehR-zz

Copy link
Copy Markdown
Contributor

@Wraith2 Thanks! We will start review on this changes.

@AfsanehR-zz AfsanehR-zz added this to the 3.0 milestone Mar 19, 2019
@Wraith2

Wraith2 commented Mar 19, 2019

Copy link
Copy Markdown
Contributor Author

If you're time constrained the changes in #34049 will be more valuable than this PR.

@AfsanehR-zz

Copy link
Copy Markdown
Contributor

same as #36664 will need to run DataAccess tests.

Comment thread src/System.Data.SqlClient/src/System/Data/SqlClient/SqlCommand.cs Outdated
Comment thread src/System.Data.SqlClient/src/System/Data/SqlClient/SqlConnection.cs Outdated
@Wraith2

Wraith2 commented Apr 23, 2019

Copy link
Copy Markdown
Contributor Author

Merge updated. Can you make sur to squash when merging to master please.

@ViktorHofer ViktorHofer requested a review from saurabh500 May 18, 2019 17:34
@ViktorHofer

ViktorHofer commented May 18, 2019

Copy link
Copy Markdown
Member

@saurabh500 please review, looks like this is ready.

@ViktorHofer

Copy link
Copy Markdown
Member

/azp run corefx-ci

@dotnet dotnet deleted a comment from azure-pipelines Bot May 18, 2019
@azure-pipelines

Copy link
Copy Markdown

Azure Pipelines successfully started running 1 pipeline(s).

@Wraith2

Wraith2 commented May 18, 2019

Copy link
Copy Markdown
Contributor Author

All SqlClient PR's are waiting on the team integrating Microsoft.Data.SqlClient.

@karelz karelz added the blocked Issue/PR is blocked on something - see comments label May 22, 2019
@karelz

karelz commented May 22, 2019

Copy link
Copy Markdown
Member

Marking as blocked then.

@stephentoub

stephentoub commented Jul 1, 2019

Copy link
Copy Markdown
Member

This is marked as 3.0 and "blocked". When is it going to be unblocked/merged or closed? The bar is moving higher for 3.0 changes, and it's unlikely to make it in if it's not merged in the next week or so; and if it is merged in the next week or so, there will be very little time to react to any fallout.

@Wraith2

Wraith2 commented Jul 1, 2019

Copy link
Copy Markdown
Contributor Author

Given the speed of movement on SqlClient and with no review so far it's too large a change to consider at this point. I'd advise moving it to future.

I was advised that work done in System.Data.SqlClient would be ported into Microsoft.Data.SqlClient so it may not end up getting merged here. Until we see some code from M.D.SqlClient pretty much everything related to sqlclient is blocked and unknown so the same applies to all my open PR's.

@karelz karelz modified the milestones: 3.0, 5.0 Jul 17, 2019
@adamsitnik adamsitnik added the tenet-performance Performance related issue label Jul 31, 2019
@maryamariyan

maryamariyan commented Aug 1, 2019

Copy link
Copy Markdown

@Wraith2 doesn't seem like this PR is being actively worked on or will be done in the next few days.
Also some files have conflict now.
@divega is there anyone who can do the review while @saurabh500 is away?
If not we could close this PR and reopen later.

@Wraith2

Wraith2 commented Aug 1, 2019

Copy link
Copy Markdown
Contributor Author

Unless someone reviews it and requests changes it's done, it doesn't need further work from me. I didn't update it because there was no point constantly rebasing or merging when there was no-one looking at it. Should anyone decide to pick it up and investigate it's a simple matter to get it up to date.

This and all my other SqlClient PR's are just waiting for the SqlClient team.

@maryamariyan

Copy link
Copy Markdown

cc: @afsanehr

@danmoseley

Copy link
Copy Markdown

@cheenamalhotra, @Gary-Zh , @David-Engel what do you want to do with this PR? Perhaps at this point it shoudl transfer to https://github.com/dotnet/SqlClient ?

I am going to close it since it's been 2 months but if this is a valuable change it would be good to make sure it is not lost. Thanks @Wraith2 .

@danmoseley danmoseley closed this Aug 6, 2019
@cheenamalhotra

Copy link
Copy Markdown
Member

Hi @danmosemsft @Wraith2

Yes the PR changes will be pulled up in Microsoft.Data.SqlClient, and they are being tracked. We have not forgotten them, they're just not falling in our priority list as of now. We're clearing up backlog and preparing for GA hence not adding more changes for M.D.SqlClient.

Post GA 1.0, we will come back to them and if needed, we shall consider back-porting to System.Data.SqlClient as well, depending on the changes.

Thank you for your patience! 🙏

@cheenamalhotra

Copy link
Copy Markdown
Member

Also adding acknowledgement note for @Wraith2

This PR is being tracked and will be picked up for dotnet/SqlClient. Appreciate your patience for some more time while we come back to review and merge your contributions! 🙏

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

Labels

area-System.Data.SqlClient blocked Issue/PR is blocked on something - see comments tenet-performance Performance related issue

Projects

None yet

Development

Successfully merging this pull request may close these issues.