是否有可能在同一个IEnumerable上链接几个LINQ查询?
一些背景,
我有一些文件,大小为20-50Gb,它们不适合内存。有些代码解析来自这样一个文件的消息,基本上是这样做的:
public IEnumerable<Record> ReadRecordsFromStream(Stream inStream) {
Record msg;
while ((msg = ReadRecord(inStream)) != null) {
yield return msg;
}
}
这允许我对记录执行有趣的查询。 例如找到记录的平均持续时间
var records = ReadRecordsFromStream(stream);
var avg = records.Average(x => x.Duration);
或者每小时/分钟的记录数
var x = from t in records
group t by t.Time.Hour + ":" + t.Time.Minute into g
select new { Period = g.Key, Frequency = g.Count() };
还有十几个我想运行的查询来从这些记录中提取相关信息。一些简单的查询当然可以组合在一个查询中,但这似乎很快就无法区分。
现在,每次运行这些查询时,我都必须从头开始读取文件,重新编写所有记录 - 解析20Gb文件20次需要花费时间,这是浪费。
我能做些什么才能只对文件进行一次传递,但对它运行几个linq查询?
答案 0 :(得分:5)
您可能需要考虑使用Reactive Extensions。我使用它已经有一段时间了,但你可能会创建一个Subject<Record>
,将所有查询附加到它(适当的IObservable<T>
变量),然后连接数据源。这将通过各种聚合推送所有数据,仅从磁盘读取一次。
虽然确切的细节没有自己下载最新的版本,但我在博客上写了几次:part 1; part 2。 (我抱怨第1部分中缺少的各种功能被添加:)
答案 1 :(得分:0)
我之前已经为3-10MB /文件的日志做了这个。没有达到该文件大小,但我尝试在1GB +总日志文件中执行此操作,而不占用大量RAM。您可以尝试我did。
答案 2 :(得分:-1)
有一种技术可以让你做这种事情。它被称为数据库:)