.NET PLINQ与异步性能的比较

问题描述 投票:0回答:1

给出这段PLINQ代码。

        public static IEnumerable<Tuple<string, string>> PlinqFileProcessingLimitedCores(int nr_of_cores) 
    {
        string archiveDirectory = @"C:\Dotnet46Examples";

        return (from file in Directory.EnumerateFiles(archiveDirectory, "*.cs", SearchOption.AllDirectories)
                from line in File.ReadLines(file).AsParallel().WithDegreeOfParallelism(nr_of_cores)
                where line.Contains("Console")
                select new Tuple<string, string>(file, line));
    }

它返回所有包含Console这个词的文件的所有行。

我试着写了更快的异步版本,然而结果都比PLINQ慢了很多,例如:。

        public static async Task<ConcurrentBag<Tuple<string, string>>> FileProcessingAsync()
    {
        string archiveDirectory = @"C:\Dotnet46Examples";
        var bag = new ConcurrentBag<Tuple<string, string>>();
        var tasks = Directory.EnumerateFiles(archiveDirectory, "*.cs", SearchOption.AllDirectories)
               .Select(file => ProcessFileAsync(bag, file));
        await Task.WhenAll(tasks);  
        return bag;
    }

        static async Task ProcessFileAsync(ConcurrentBag<Tuple<string, string>> bag, string file)
    {
        String line;
        using (StreamReader reader = File.OpenText(file))
        {
            while (reader.Peek() >= 0)
            {
                line = await reader.ReadLineAsync(); 
                if (line != null)
                {
                    if (line.Contains("Console"))
                    {
                        bag.Add(new Tuple<string, string>(file, line));
                    }
                }
            }        
        }
    }

为什么异步代码这么慢(在我的笔记本上是1000因子)? 更好的代码是怎样的? 这个问题不适合异步吗?

c# .net asynchronous plinq
1个回答
3
投票

你的并行例子是(同步地)一次一行一行地把文件读到内存中,然后(并行地)搜索文本。这可能是最快的解决方案,因为在Windows上通常同步文件IO比异步快。

我试着写了更快的异步版本

"异步 "并不意味着 "更快"。它的意思是 "不阻塞调用线程"。异步代码会有额外的开销,所以一般来说是 较慢. 异步代码的好处不是速度,而是释放线程。只有当这些线程有其他工作要做时,这才是一个好处;例如,在服务器环境中,它们可以处理其他请求。

还有一个问题是,像 File.OpenText 实际上不允许异步访问,所以什么是 ReadLineAsync 实际上是在线程池上运行同步工作,然后进行异步处理。但即使你有一个正确的异步实现,也不会比同步读取文件快。

© www.soinside.com 2019 - 2024. All rights reserved.