Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/linq/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 使用LINQ高效地从文件计算总计_C#_Linq - Fatal编程技术网

C# 使用LINQ高效地从文件计算总计

C# 使用LINQ高效地从文件计算总计,c#,linq,C#,Linq,我正在读取一个文件,并将其中的每一行转换为一个类,让我们称之为记录,并返回每个记录,因为它是使用IEnumerable读取的,并且返回 因此,每当我对枚举执行操作时,我才开始实际执行这些读取,例如对枚举执行求和或使用foreach对其进行迭代 我确实需要检查每条记录,然后将其转换为数据库,但由于在我工作之前的数据库设计,我需要数据库中每条记录的总计,因此在开始将它们转换为数据库之前,我需要这些总计 目前,在我开始迭代枚举之前,我有五个独立的.Count()或.Sum()操作在我的枚举上(例如in

我正在读取一个文件,并将其中的每一行转换为一个类,让我们称之为
记录
,并返回每个
记录
,因为它是使用
IEnumerable
读取的,并且
返回

因此,每当我对枚举执行操作时,我才开始实际执行这些读取,例如对枚举执行求和或使用
foreach
对其进行迭代

我确实需要检查每条记录,然后将其转换为数据库,但由于在我工作之前的数据库设计,我需要数据库中每条记录的总计,因此在开始将它们转换为数据库之前,我需要这些总计

目前,在我开始迭代枚举之前,我有五个独立的
.Count()
.Sum()
操作在我的枚举上(例如
int I=records.Sum(r=>r.SomeField)
int j=records.Count(r=>r.IsSomethingTrue)
)。这些计数或总和中的每一个都将在整个文件中循环以分别计算每一个。我对这种行为不太满意,我想找到一种更有效的方法


如果有什么不同的话,我使用的是.NET3.5。

效率不是LINQ的强项。。。您需要在这里用手动循环替换一些LINQ东西

您似乎需要对数据进行两次传递。一个用于聚合:

var sum = 0; //etc.
foreach (var item in items) {
 //compute all 5 aggregates here
}
然后再翻译数据:

items.Select(item => Translate(item, aggregates))
您是否应该缓冲
(例如使用
ToList
)取决于可用内存是否可以容纳这些项


您可以使用
Aggregate
在一次过程中执行所有5次聚合,但这在任何方面都不比循环好。它速度较慢,代码多得多,而且可以说代码难以辨认。

您可以使用自己的
struct
在通过可枚举对象的一次过程中计算一些值

public struct ComplexAccumulator
{
    public int TotalSumField { get; set; }

    public int CountSomethingTrue { get; set; }
}
现在您可以使用
Aggreagate
扩展方法来累积值:

records.Aggregate(default(ComplexAccumulator), (a, r) => new ComplexAccumulator
{
    TotalSumFiled = a.TotalSumField + r.SumField,
    CountSomethingTrue = a.CountSomethingTrue + r.IsSomethingTrue ? 1 : 0,
});

您可以使用合适的
Tuple
实例来代替
struct
,例如
Tuple

之类的东西。您考虑过存储过程吗?总数来自文件,而不是数据库。我想使用聚合是正确的,但我不确定如何使用,我会试一试,谢谢。那么慢吗?不过,你在易读性方面做得很好。@Logan slow是相对的。每次迭代需要2个vcalls和一个委托调用。JIT并不能使这一速度加快。都是非常间接的代码。这取决于聚合的速度。如果只是5次添加,那么与循环相比,您可以轻松松开2-3倍。旧的JIT和RyuJIT在结构处理方面也非常糟糕。预期会有许多加载和存储到内存中。不使用寄存器。是的,我不知道我正在处理的卷是否会在这方面受到很大影响,但我也在尝试考虑增长(这就是为什么我不只是将所有内容都放到内存中并从中工作)。我想从可读性的角度来看,循环是更好的选择。谢谢。@Logan是的,很简单。如果您想使其成为一个表达式,就像聚合调用是(而循环不是)一样,那么您可以将其放入函数中。