C# 如何在同一数据文件上运行多个LINQ查询
我不熟悉C# 如何在同一数据文件上运行多个LINQ查询,c#,linq,C#,Linq,我不熟悉LINQ,目前正在使用它处理csv格式的大型数据集(50万条记录)。我正在使用StreamReader打开文件并实现IEnumerable接口以填充结果。下面您可以看到阅读代码的主要部分: IEnumerator<Person> IEnumerable<Person>.GetEnumerator() { using (StreamReader streamReader = new StreamReader(filename)){ strea
LINQ
,目前正在使用它处理csv格式的大型数据集(50万条记录)。我正在使用StreamReader
打开文件并实现IEnumerable
接口以填充结果。下面您可以看到阅读代码的主要部分:
IEnumerator<Person> IEnumerable<Person>.GetEnumerator()
{
using (StreamReader streamReader = new StreamReader(filename)){
streamReader.ReadLine();
while (!streamReader.EndOfStream){
string[] values = streamReader.ReadLine().Split(new char[] { ',' });
Person p = new Person();
p.Name = values[0];
p.Age = Convert.ToInt16(values[1]);
p.Score = Convert.ToDouble(values[2]);
p.PlotArea = Convert.ToInt16(values[3]);
p.ForecastConsumption = Convert.ToDouble(values[4]);
p.Postcode = values[5];
p.PropertyType = values[6];
p.Bedrooms = Convert.ToInt16(values[7]);
p.Occupancy = Convert.ToInt16(values[8]);
yield return p;
}
}
}
IEnumerator IEnumerable.GetEnumerator()
{
使用(StreamReader StreamReader=新StreamReader(文件名)){
streamReader.ReadLine();
而(!streamReader.EndOfStream){
string[]values=streamReader.ReadLine().Split(新字符[]{',});
人员p=新人员();
p、 名称=值[0];
p、 年龄=转换为16(值[1]);
p、 分数=Convert.ToDouble(值[2]);
p、 PlotArea=Convert.ToInt16(值[3]);
p、 ForecastConsumption=Convert.ToDouble(值[4]);
p、 邮政编码=数值[5];
p、 PropertyType=值[6];
p、 卧室=转换为16(值[7]);
p、 占用率=转换为16(值[8]);
收益率p;
}
}
}
下面是一个典型的查询:
var query = from person in reader
where person.Score > 36.55 && person.Bedrooms < 3
select person;
var query=来自读卡器中的人员
其中人员得分>36.55且人员卧室<3
选择人员;
我的问题是,每次我想运行一个查询,StreamReader
都必须打开该文件。是否有任何方法可以一次打开文件并运行多个查询
仅供参考,我对LINQ印象深刻,运行上面的查询需要1.2秒。只是我会为数据集运行很多规则
我的问题是,每次我想运行查询时,StreamReader都必须打开文件。是否有任何方法可以一次打开文件并运行多个查询
最简单的方法是将整个文件加载到一个列表中,例如
var list = reader.ToList();
// Now run multiple queries over list
显然,这将占用大量内存,但这将是最简单的方法。如果要将多个查询连接在一起,则必须准确地确定要执行的操作—LINQ中的组合模型主要是将查询操作链接在一起,而不是从同一个源构建多个查询
否则,如果“一次查询多个”或“将整个文件加载到内存”的复杂性对您都不起作用,那么您很可能会被多次加载所困扰
中间的一个可能更高效的选项是将所有行读取到内存中(因此只执行一次磁盘活动),然后多次解析这些行。这将在IO方面更有效,但在CPU方面更糟糕
我的问题是,每次我想运行查询时,StreamReader都必须打开文件。是否有任何方法可以一次打开文件并运行多个查询
最简单的方法是将整个文件加载到一个列表中,例如
var list = reader.ToList();
// Now run multiple queries over list
显然,这将占用大量内存,但这将是最简单的方法。如果要将多个查询连接在一起,则必须准确地确定要执行的操作—LINQ中的组合模型主要是将查询操作链接在一起,而不是从同一个源构建多个查询
否则,如果“一次查询多个”或“将整个文件加载到内存”的复杂性对您都不起作用,那么您很可能会被多次加载所困扰
中间的一个可能更高效的选项是将所有行读取到内存中(因此只执行一次磁盘活动),然后多次解析这些行。这在IO方面效率更高,但在CPU方面更差。您的情况将是在以下两个方面进行性能权衡:
File.ReadLines
,它在文件IO上提供了一个很好的IEnumerable接口:
public Person ReadPerson(string[] personLine)
{
Person p = new Person();
p.Name = personLine[0];
p.Age = Convert.ToInt16(personLine[1]);
p.Score = Convert.ToDouble(personLine[2]);
p.PlotArea = Convert.ToInt16(personLine[3]);
p.ForecastConsumption = Convert.ToDouble(personLine[4]);
p.Postcode = personLine[5];
p.PropertyType = personLine[6];
p.Bedrooms = Convert.ToInt16(personLine[7]);
p.Occupancy = Convert.ToInt16(personLine[8]);
}
使用方法:
var file = File.ReadLines("/filepath/")
.Select(line => ReadPerson(line.Split(',')));
var query = from person in file
where person.Score > 36.55 && person.Bedrooms < 3
select person;
var file=file.ReadLines(“/filepath/”)
.Select(line=>ReadPerson(line.Split(','));
var query=来自文件中的人员
其中人员得分>36.55且人员卧室<3
选择人员;
您的情况将在以下两方面进行性能权衡:
File.ReadLines
,它在文件IO上提供了一个很好的IEnumerable接口:
public Person ReadPerson(string[] personLine)
{
Person p = new Person();
p.Name = personLine[0];
p.Age = Convert.ToInt16(personLine[1]);
p.Score = Convert.ToDouble(personLine[2]);
p.PlotArea = Convert.ToInt16(personLine[3]);
p.ForecastConsumption = Convert.ToDouble(personLine[4]);
p.Postcode = personLine[5];
p.PropertyType = personLine[6];
p.Bedrooms = Convert.ToInt16(personLine[7]);
p.Occupancy = Convert.ToInt16(personLine[8]);
}
使用方法:
var file = File.ReadLines("/filepath/")
.Select(line => ReadPerson(line.Split(',')));
var query = from person in file
where person.Score > 36.55 && person.Bedrooms < 3
select person;
var file=file.ReadLines(“/filepath/”)
.Select(line=>ReadPerson(line.Split(','));
var query=来自文件中的人员
其中人员得分>36.55且人员卧室<3
选择人员;
这应该可以:
return from line in File.ReadAllLines(filename)
let values = line.Split(new char[] { ',' })
select new Person{
Name = values[0];
Age = Convert.ToInt16(values[1]);
Score = Convert.ToDouble(values[2]);
PlotArea = Convert.ToInt16(values[3]);
ForecastConsumption = Convert.ToDouble(values[4]);
Postcode = values[5];
PropertyType = values[6];
Bedrooms = Convert.ToInt16(values[7]);
Occupancy = Convert.ToInt16(values[8]);
};
这应该起作用:
return from line in File.ReadAllLines(filename)
let values = line.Split(new char[] { ',' })
select new Person{
Name = values[0];
Age = Convert.ToInt16(values[1]);
Score = Convert.ToDouble(values[2]);
PlotArea = Convert.ToInt16(values[3]);
ForecastConsumption = Convert.ToDouble(values[4]);
Postcode = values[5];
PropertyType = values[6];
Bedrooms = Convert.ToInt16(values[7]);
Occupancy = Convert.ToInt16(values[8]);
};
如果您是.net4+,您可以完全不用StreamReader,而是使用File.ReadLines。它做同样的事情(即允许您枚举文件而不将其全部加载到内存中)。
reader
是什么类型?如果你想在内存中完成所有工作,你也可以使用File.ReadAllLines
看看这个,如果文件很大,你可以从它开始构建一个共享(多线程)缓存(只需记住每个线程库中的当前行/位置)我也喜欢LINQ,但是在没有LINQ的情况下重写该查询,只需要不到一秒钟的时间(如果你牺牲一点代码,我会说半秒)。如果你是.net4+,你可以完全不用StreamReader,而是使用File.ReadLines。它做同样的事情(即允许你枚举一个文件而不将其全部加载到内存中).reader
是什么类型?如果您想在内存中完成所有操作,也可以使用文件。ReadAllLines
看看这个,如果文件很大,您可以从它开始构建共享(多线程)cach