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
This repository was archived by the owner on Jan 23, 2023. It is now read-only.
/corefxPublic archive

Optimize overlapped I/O FileStream.CopyToAsync implementation on Windows#11569

Merged

Conversation

@stephentoub
Copy link
Member

Add an override of CopyToAsync in the Windows implementation of FileStream for use when the stream is constructed in async mode.

The base stream implementation does a simple loop that reads from the source and writes to the destination. For the Windows implementation of FileStream in async mode, each of these read operations involves overhead, such as allocating the task to return from the operation, registering with the providing cancellation token, etc. For CopyToAsync, we’re responsible for all of the reads, which means we can avoid these per-read costs.

Copying a 10MB file to a MemoryStream with the default buffer size and with a cancelable token improved throughput by 50%, and (not including the copy buffer) reduced the number of allocations from 860 to 11 and the bytes allocated from 52K to ~730b. Copying a 100 byte file to a MemoryStream with the default buffer size and with a non-cancelable token improved throughput by 30% and (not including the copy buffer) reduced the number of allocations from 46 to 11 and the bytes allocated from 1.1K to ~670b.

(I briefly explored adding an override for when in sync mode, but the savings there aren’t nearly as significant or measurable. At best it can avoid a Task per read. We can look more seriously at doing that separately, if desired; that could likely also be done for the Unix implementation.)

Fixes #11539
cc:@ericstj,@JeremyKuhne,@ianhays,@davidfowl

benaadams, omariom, dVakulen, davidfowl, rkeithhill, ReubenBond, gauffininteractive, DavidRouyer, AlekseyKonakov, ianhays, and 3 more reacted with thumbs up emoji
// whatever read operation may currently be in progress, if there is one. It's possible the cancellation
// request could come in between operations, in which case we flag that with explicit calls to ThrowIfCancellationRequested
// in the read/write copy loop.
cancellationReg=cancellationToken.Register(s=>
Copy link
Member

Choose a reason for hiding this comment

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

Can you just avoid this if cancellationToken = None?

Copy link
MemberAuthor

Choose a reason for hiding this comment

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

Yes, I'll do that, though it won't save very much: one of the first things Register does is check that (or, rather, CanBeCanceled), and exits early if it can't.

@davidfowl
Copy link
Member

LGTM

@stephentoubstephentoubforce-pushed thefilestream_copytoasync branch 2 times, most recently from119c770 to93e928eCompareSeptember 10, 2016 20:53
unsafe
{
lock(innerAwaitable.CancellationLock)// synchronize with cleanup of the overlapped
{
Copy link
Contributor

Choose a reason for hiding this comment

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

Nit: indentation

Copy link
MemberAuthor

Choose a reason for hiding this comment

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

Fixed

@stephentoubstephentoubforce-pushed thefilestream_copytoasync branch 4 times, most recently frombd71bdb to5b4ece3CompareSeptember 11, 2016 13:23
@stephentoub
Copy link
MemberAuthor

I've fixed the issue that was causing the CI runs to hang.

@davidfowl
Copy link
Member

😄 Waiting for this change


publicoverrideTaskCopyToAsync(Streamdestination,intbufferSize,CancellationTokencancellationToken)
{
// Validate arguments as would the base implementation
Copy link
Member

Choose a reason for hiding this comment

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

These lines hurt my eyes. Is this really in line with our style guidelines?

Copy link
MemberAuthor

Choose a reason for hiding this comment

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

Is this really in line with our style guidelines?

We allow for single lines like this. I find this easier to follow than tripling the size of the arg validation by moving the bodies to their own lines and surrounding by braces on their own lines. But I don't feel strongly about it and can change it.

Copy link
Member

Choose a reason for hiding this comment

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

My preference is to match the pattern in the rest of the file.

Copy link
MemberAuthor

Choose a reason for hiding this comment

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

Ok.

@JeremyKuhne
Copy link
Member

lgtm, thanks

Add an override of CopyToAsync in the Windows implementation of FileStream for use when the stream is constructed in async mode.The base stream implementation does a simple loop that reads from the source and writes to the destination.  For the Windows implementation of FileStream in async mode, each of these read operations involves overhead, such as allocating the task to return from the operation, registering with the providing cancellation token, etc.  For CopyToAsync, we’re responsible for all of the reads, which means we can avoid these per-read costs.Copying a 10MB file to a MemoryStream with the default buffer size and with a cancelable token improved throughput by 50%, and (not including the copy buffer) reduced the number of allocations from 860 to 11 and the bytes allocated from 52K to ~730b. Copying a 100 byte file to a MemoryStream with the default buffer size and with a non-cancelable token improved throughput by 30% and (not including the copy buffer) reduced the number of allocations from 46 to 11 and the bytes allocated from 1.1K to ~670b.(I briefly explored adding an override for when in sync mode, but the savings there aren’t nearly as significant or measurable.  At best it can avoid a Task per read.  We can look more seriously at doing that separately, if desired; that could likely also be done for the Unix implementation.)
@stephentoubstephentoub merged commitf3a2e16 intodotnet:masterSep 13, 2016
@stephentoubstephentoub deleted the filestream_copytoasync branchSeptember 13, 2016 01:49
@karelzkarelz modified the milestone:1.2.0Dec 3, 2016
picenka21 pushed a commit to picenka21/runtime that referenced this pull requestFeb 18, 2022
…pytoasyncOptimize overlapped I/O FileStream.CopyToAsync implementation on WindowsCommit migrated fromdotnet/corefx@f3a2e16
Sign up for freeto subscribe to this conversation on GitHub. Already have an account?Sign in.

Reviewers

No reviews

Assignees

No one assigned

Labels

None yet

Projects

None yet

Milestone

2.0.0

Development

Successfully merging this pull request may close these issues.

8 participants

@stephentoub@davidfowl@JeremyKuhne@justinvp@jkotas@ericstj@karelz@dnfclas

[8]ページ先頭

©2009-2025 Movatter.jp