-
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
FileStream.Windows useAsync WriteAsync calls blocking apis #25905
Comments
|
Is this using a FileStream or is it using something derived from FileStream? |
It's got more overhead and scales better; that's the tradeoff. We could look at using an IValueTaskSource to back the new ValueTask-returning overload, but I'm afraid that ship may have sailed at this point, as it's an observable change and we're locking down the 2.1 release. |
https://stackoverflow.com/questions/49827208/ado-async-all-the-way-down-the-tubes/49837693#49837693 Iterate 1,000,000 times .Write(bytes)Total Elapsed Time: 0.1750803 seconds Iterate 1,000,000 times .WriteAsync(bytes)Total Elapsed Time: 3.1865426 seconds |
And to be clear, the times Ben listed are not correct. The performance is much worse when Async.
That's what I've been thinking is that when quick-iterating, it's just not worth the async overhead per write. Especially if you've already got your data queued up. |
using (var fs = new FileStream(FilePath, FileMode.Append,
FileAccess.Write, FileShareMode, bufferSize: 4096 * 4, useAsync: true)) Overloads weren't looking right; as didn't go through |
Closing for now; was concerned it wasn't taking the overlapped path, but that seem to not be the case - was a build mix up; probably from switching runtimes, Will open a new one if I get a smaller repo for perf |
@benaadams, I don't understand what the action item is meant to be on this issue. |
With this one weird trick... dotnet/coreclr#17581? |
Pre
Post
|
There's a second behviour difference. WriteAsync will issue a Flush+Write if it would over fill the buffer; whereas Write will issue a Flush and then copy into the cleared buffer (if under buffer size; otherwise Write); so may have an extra Write creeping in - but that's a more involved item to look at, at some point in future. |
@benaadams Make sure you're you are using the latest code. Your previous code was not completing all the writes. It just cut short and made the times look strange. They are much worse. (I added an assertion that compares the total bytes written to the total bytes of the file.) A successful benchmark has to have all the bytes written. |
Am using latest code; also using a very fast SSD so it would be much worse without it. It looks like the main cause of slow down for async vs blocking is the number of extra file interactions that occur in that path; rather than it being async. |
e.g. |
Fixed by #49975, please expect a blog post with all the details and perf numbers in April (before we ship preview 4) |
e.g SetEndOfFile in the async path is 50% of the time and it doesn't need to be called (as WriteFile will expand the File).
SetEndOfFile is also a blocking api itself; so expanding the file using it blocks the thread for as much time (or more) as the async saves blocking.
Previous
Seen in electricessence/AsyncFileWriter#1 (Windows 10; netcoreapp2.0 and netcoreapp2.1)
Non-async (just for
FileStream.Write
)Making the change electricessence/AsyncFileWriter@752f7ef
useAsync = true
andfs.Write(
=>await fs.WriteAsync(
Causes a dramatic slow down:
Seems to use a lot of threads, though maybe that's Channels
The text was updated successfully, but these errors were encountered: