【问题标题】:plinq select count where all functions evaluate trueplinq 选择计数,其中所有函数都评估为真
【发布时间】:2012-11-06 17:19:21
【问题描述】:

我有一组数据都是双打的: 100行20列

我将数据拉到一个 IEnumerable 列表中:

var RowsOfData = File.ReadLines(dll.Globals.OutputDir +     dll.Globals.filename).Select(a => a.Split(',').ToList());

var FilteredRowsToday = (from n in RowsOfData
       where n[1] == 1
       orderby n[0] descending
       select n);

然后我有一组函数,它们对每个数据行进行简单检查,每个都返回一个 Bool。 我想要的是计算每个函数评估为真的行数。 然后,当我扩大项目规模时,如果可能的话,我希望尽快并行处理,我已经尝试过:

foreach (var row in FilteredRowsToday) {  
is f1() true, is f2() true 
etc
}

看起来很慢 我尝试过并行处理

foreach (var row in FilteredRowsToday.AsParallel())

没有更快

我现在在想这样的事情:

var TotalTrue = FilteredRowsToday.Select(item => f1() & f2() & f3()).Count();

如果这是一个更好的陈述点,我可以预处理数据以将每个函数的评估结果提供为一种二进制网格?

F1, f2, f3 etc
1, 0, 0 row 1
1, 1, 1 row 2 etc

欢迎提出建议!

【问题讨论】:

  • 100 行是一个非常小的计数。为什么你的计算这么慢?有些方法需要很长时间吗?

标签: .net plinq


【解决方案1】:

如果您只对所有三个函数计算结果为 true 的计数感兴趣,那么这就足够了:

var TotalTrue = FilteredRowsToday.Count(item => f1() & f2() & f3());

至于为什么慢,可能是你的功能造成的。

您可以尝试只评估行,直到所有三个函数都返回 true,或者其中至少一个返回 false,例如

var TotalTrue = FilteredRowsToday.Count(item => f1() && f2() && f3());

即如果f1() 的计算结果为false,则无需费心进行其余的验证。

更新:如果您的函数没有进行任何资源密集型检查,那么并行 LINQ 不会对您有多大好处(更多信息 here)。

【讨论】:

  • Tobias 等人,非常感谢,我确实有一个列表来检查我以这种方式检查的每个函数的返回: bool AllConditionsTrue = conditions.TrueForAll(o => o);效果很好,但我也喜欢你上面的。至于每个函数的计算相对成本:早期,有些函数非常简单,有些函数更复杂,这就是为什么我可以先对函数进行预处理,然后将二进制网格类型结构的结果作为一个单独的过程计算.
  • @user1796185:如果大部分处理时间都花在了预处理上,那么预处理不会加快你的进程。计算结果不是问题。我的建议是关注你的评估方法,看看你可以在哪里优化它们。当您检查结果时,您甚至可以按复杂程度对它们进行评估,从而确保首先运行便宜(快速)的方法,并且只有在其他方法评估为 true 时才运行更密集的方法。
【解决方案2】:

正如我所见,您正在一次读取文件,它是一种逗号分隔的文件。 如果您在读取时从文件中生成记录,它将允许您处理它们,直到您等待下一次读取。

private IEnumerable<string> GetRecords(string fileName) {
    using (StreamReader reader = File.OpenText(fileName))
            {
                string line = reader.ReadLine();
                while (line != null)
                {   
                   yield return line.Split(',');
                   line = reader.ReadLine();
                 }
             }
}

您还花了一些时间将Split 的结果转换为List,这已经是array 并且具有执行查询所需的索引访问权限。

我还建议应用之前建议的优化,例如使用 .Count(item =&gt; f1() &amp; f2() &amp; f3()); 而不是 .Select(item =&gt; f1() &amp; f2() &amp; f3()).Count();

尽管如此,我不相信这些优化中的任何一项都会在如此少量的数据下带来任何改进。如果您发布一些有关您处理部分代码的详细信息,我认为我们可以为您提供更好的帮助。

【讨论】:

    猜你喜欢
    • 2023-04-03
    • 2013-03-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-08-25
    • 1970-01-01
    • 2014-11-20
    • 1970-01-01
    相关资源
    最近更新 更多