-
Notifications
You must be signed in to change notification settings - Fork 258
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
Consider using async I/O in .NET 6 #10887
Comments
@dtivel I created some benchmarks to test sync vs async vs mmap IO for package extraction: https://github.com/zivkan/Benchmarks/blob/main/WritePerformance/PackageExtraction.cs On .NET Framework I found that async IO is about 50% slower than sync IO, and even on .NET 6, it's only about the same perf as sync IO, it wasn't meaninfully faster (my memory was that it was still slightly slower, since async has additional scheduling overheads that blocking IO does not, but I don't remember the exact numbers, as my main concern was sync IO vs mmap). As long as Visual Studio is using the .NET Framework, it would be a huge perf regression to switch to async IO, unless there's a trick I don't know about. Even in .NET 6, it's a lot of work for not much benefit, according to my benchmarks. |
That's great. Feel free to close this issue then. |
Looking at the blog post, and the linked NuGet PR, I see that my benchmark was doing async IO wrong, causing it to use sync over async. Hopefully I fixed it properly (locally, I haven't yet pushed to my repo), I got the following results: .NET 6
.NET Framework 4.8
I tested with 8 and 32 parallel extractions because my machine has 8 physical core, 16 logical core CPU. From my previous tests running 1, 2, 4, 8, 16, and 32 max parallel extractions, I found 8 was where significant performance gains stopped on this hardware. I tested 32 here because the point of async is to allow more efficient application task switching compared to operating system thread switching, so max parallel < (logical) processor with async APIs is theoretically always slower than blocking APIs because of async task scheduling overheads. I also had Windows Defender exclude the write directory from scanning, because on .NET Framework this has a massive perf penalty that I'm slowing trying to investigate and report to the Windows Defender team. So, I confirm that on .NET 6 async is only slightly slower, even when MaxParallel is greater than Environment.ProcessorCount. Whereas on .NET Framework 4.8, async IO takes 10x as long (assuming the Windows Defender perf impact is mitigated). Since there doesn't appear to be any scenario where async file IO benefits package extraction, I'm closing this issue. |
Reimplemented async I/O in .NET 6 offers much improved performance benefits. See this for details.
We disabled async I/O in NuGet/NuGet.Client#2488 based on dotnet/runtime#27643. .NET 6 fixes this problem.
Note that we still would need to preserve current performance on older frameworks (e.g.: NuGet.exe on .NET Framework 4.8).
The text was updated successfully, but these errors were encountered: