This an old post, but I was curious about this question with a current version of C# with files on a local SSD drive. I used BenchmarkDotNet to measure performance of reading files in parallel + async.
From the results of my test with, parallel code is ~3.4 times as fast as serial. I suspect this likely has to due more-so with utilization of multiple cores and keeping the IO pipeline full.
Benchmark code
[SimpleJob(RuntimeMoniker.Net60, baseline: true)] [RPlotExporter] public class FileReadBenchmark { private List<string> _files = new List<string>(); [Params(10, 100)] public int Count; [GlobalSetup] public void Setup() { _files = Directory.GetFiles(@"C:\LocalDirectory\") .Take(Count) .ToList(); } [Benchmark] public void ParallelFileRead() { Parallel.ForEach(this._files, (f) => { _ = File.ReadAllLines(f); }); } [Benchmark] public async Task ParallelFileReadAsync() { await Parallel.ForEachAsync(this._files, async (f, c) => { await File.ReadAllLinesAsync(f, c); }); } [Benchmark] public void SequentialFileRead() { this._files.ForEach((f) => { _ = File.ReadAllLines(f); }); } [Benchmark] public async Task SequentialFileReadAsync() { foreach (var f in _files) { await File.ReadAllLinesAsync(f); } } }
BenchmarkDotNet=v0.13.3, OS=Windows 10 (10.0.19044.2364/21H2/November2021Update) 11th Gen Intel Core i7-1185G7 3.00GHz, 1 CPU, 8 logical and 4 physical cores .NET SDK=7.0.101 [Host] : .NET 6.0.12 (6.0.1222.56807), X64 RyuJIT AVX2 .NET 6.0 : .NET 6.0.12 (6.0.1222.56807), X64 RyuJIT AVX2 Job=.NET 6.0 Runtime=.NET 6.0 | Method | Count | Mean | Error | StdDev | Median | Ratio | |------------------------ |------ |----------:|----------:|----------:|----------:|------:| | ParallelFileRead | 10 | 1.166 ms | 0.0232 ms | 0.0595 ms | 1.167 ms | 1.00 | | | | | | | | | | ParallelFileReadAsync | 10 | 1.604 ms | 0.0385 ms | 0.1130 ms | 1.563 ms | 1.00 | | | | | | | | | | SequentialFileRead | 10 | 3.970 ms | 0.0785 ms | 0.0934 ms | 3.943 ms | 1.00 | | | | | | | | | | SequentialFileReadAsync | 10 | 4.043 ms | 0.0750 ms | 0.1692 ms | 3.996 ms | 1.00 | | | | | | | | | | ParallelFileRead | 100 | 10.981 ms | 0.2060 ms | 0.1826 ms | 11.007 ms | 1.00 | | | | | | | | | | ParallelFileReadAsync | 100 | 12.573 ms | 0.1678 ms | 0.1570 ms | 12.501 ms | 1.00 | | | | | | | | | | SequentialFileRead | 100 | 38.171 ms | 1.2692 ms | 3.7423 ms | 36.319 ms | 1.00 | | | | | | | | | | SequentialFileReadAsync | 100 | 43.606 ms | 0.8559 ms | 1.1130 ms | 43.589 ms | 1.00 |