-
Notifications
You must be signed in to change notification settings - Fork 4.8k
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 our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Cache GetFileInformationByHandleEx (Length) when FileShare indicates that no one else can change it #49638
Conversation
remove finalizer from FileStream, keep it only in DerivedFileStreamStrategy and LegacyFileStreamStrategy
… functional they can now be used directly without any buffering on top of them!
…NothingToFlush_CompletesSynchronously passing
…ithin the file, not a removal and addition)
when users have a race condition in their code (i.e. they call Close when calling another method on Stream like Read).
…re not providing too much gains
…llow other processes to modify it
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The perf gains are really impressive!
@@ -40,6 +43,7 @@ internal WindowsFileStreamStrategy(SafeFileHandle handle, FileAccess access) | |||
// Note: Cleaner to set the following fields in ValidateAndInitFromHandle, | |||
// but we can't as they're readonly. | |||
_access = access; | |||
_share = FileStream.DefaultShare; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
instead of using FileStream.DefaultShare
here you can add FileShare share
to the ctor
arguments and pass FileStream.DefaultShare
from FileStream
. We are already doing similar thing:
this(path, mode, access, DefaultShare, DefaultBufferSize, DefaultIsAsync) |
@@ -32,6 +34,7 @@ internal abstract class WindowsFileStreamStrategy : FileStreamStrategy | |||
private readonly bool _isPipe; // Whether to disable async buffering code. | |||
|
|||
private long _appendStart; // When appending, prevent overwriting file. | |||
private long? _length; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
what would be the difference in the allocated memory if we would use non-nullable long
field and use negative values instead null to determine whether the field was initialized or not?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This field doesn't actually allocate for being nullable; Nullable<T>
is a struct, but it makes sense to use negatives instead.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This field doesn't actually allocate for being nullable
Is sizeof(long) == sizeof(long?)
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is sizeof(long) == sizeof(long?)?
Nope, it is 8 and 16 respectively on my machine. I thought you were referring to heap allocations, I will prefer long
for the upcoming pull request, thanks.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM so far. Questions:
- Do you plan on waiting for Adam's refactoring PR to get merged to avoid any potential conflicts, or are we expecting this PR to get merged first?
- Adam merged his rewrite PR already. Can you please rebase this?
src/libraries/System.Private.CoreLib/src/System/IO/WindowsFileStreamStrategy.cs
Show resolved
Hide resolved
src/libraries/System.Private.CoreLib/src/System/IO/WindowsFileStreamStrategy.cs
Show resolved
Hide resolved
@carlossanlop I will close this PR and send a new one that combines #49145 and this one, see also #49145 (comment).
For the upcoming PR that I mentioned above, I don't have a preference, if Adam's PR (#49750) gets in first, I can work on fixing the conflics. |
This change builds on top of #49145
Adds caching logic for
GetFileInformationByHandleEx
when the FileStream is constructed withFileShare.Read
orFileShare.None
.Fixes #49145
The following benchmark results show ~15-19% gains on
ReadAsync
when is indicated to useAsynchronous
I/O.I am using the new FileStream implementation (
DOTNET_SYSTEM_IO_USELEGACYFILESTREAM = false
).