【问题标题】:Can this LinQ statement made run multi threading - using more cpu cores这个 LinQ 语句可以运行多线程吗 - 使用更多的 cpu 内核
【发布时间】:2013-05-31 13:32:15
【问题描述】:

我已经写了下面的 linq 语句。但是由于行数太多,因此需要大量时间来处理。我的 cpu 有 8 个内核,但由于运行单线程而只使用 1 个内核。

所以我想知道这个最后的语句是否可以在多线程中运行?

        List<string> lstAllLines = File.ReadAllLines("AllLines.txt").ToList();
        List<string> lstBannedWords = File.ReadAllLines("allBaddWords.txt").
Select(s => s.ToLowerInvariant()).
Distinct().ToList();

我问的是下面的那个。那条线可以多线程工作吗?

        List<string> lstFoundBannedWords = lstBannedWords.Where(s => lstAllLines.
SelectMany(ls => ls.ToLowerInvariant().Split(' ')).
Contains(s)).
        Distinct().ToList();

C# 5,网络框架 4.5

【问题讨论】:

  • 查看了PLINQ?请注意,这并不能保证让任何东西运行得更快。
  • @AdamHouldsworth 还没有检查,但让我看看 :)
  • stackoverflow.com/questions/7582591/… (Understanding Speedup in PLINQ) 查询成本越高,PLINQ 的候选者就越好。
  • 哇,它开始使用 5 个内核,只需添加 1 个关键字,呵呵:我喜欢 C# ^^
  • @Chris .AsParallel() 我想。

标签: c# multithreading linq


【解决方案1】:

下面的 sn-p 可以使用 Parallel Tasks Library's Parallel.ForEach 方法执行该操作。下面的 sn-p 获取您拥有的“所有行”文件中的每一行,将其拆分为空格,然后在每一行中搜索禁用词。 Parallel-ForEach 应该使用您机器处理器上的所有可用内核。希望这会有所帮助。

System.Threading.Tasks.Parallel.ForEach(
    lstAllLines,
    line =>
    {
        var wordsInLine = line.ToLowerInvariant().Split(' ');
        var bannedWords = lstBannedWords.All(bannedWord => wordsInLine.Contains(bannedWord));
        // TODO: Add the banned word(s) in the line to a master list of banned words found.
    });

【讨论】:

    【解决方案2】:

    在求助AsParallel之前还有性能提升空间

    HashSet<string> lstAllLines = new HashSet<string>(
                                    File.ReadAllLines("AllLines.txt")
                                        .SelectMany(ls => ls.ToLowerInvariant().Split(' ')));
    
    List<string> lstBannedWords = File.ReadAllLines("allBaddWords.txt")
                                        .Select(s => s.ToLowerInvariant())
                                        .Distinct().ToList();
    
    List<string> lstFoundBannedWords = lstBannedWords.Where(s => lstAllLines.Contains(s))
                                        .Distinct().ToList();
    

    由于对 HasSet 的访问是 O(1)lstBannedWords 是较短的列表,您甚至可能不需要任何并行性 (TotalSearchTime=lstBannedWords.Count*O(1))。最后,您始终可以选择AsParallel

    【讨论】:

    • 不是我,但您可能希望将 lstAllLines 变量重命名为 hashAllWords 之类的名称,以使代码更易于理解。
    • @Dirk 我只是想保留 OP 的变量名。毕竟在使用VS的时候只是Refactor/Rename。
    • 实际上这并不是我正在做的事情:) 我也没有投反对票。我正在逐字逐句检查,您正在检查文字级别。
    • @MonsterMMORPG 评论前你测试了吗?
    猜你喜欢
    • 2012-05-30
    • 2014-04-13
    • 2016-05-08
    • 2016-12-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-07-28
    • 1970-01-01
    相关资源
    最近更新 更多