linq contains 效率的问题

MisterDotNet 2015-07-16 10:08:54
问:有50个班级,50个年级下总共有50000个学生,已知20个班级的班级id集合—list_class,想通过linq获取50000个学生中班级在集合list_class中的学生,使用了两段代码,linq中的contains()方法 和 字符串的indexOf()方法,其中contains()的效率非常低,请问是为什么? 代码如下:

List<int> list_class=new List<int>();//班级
list_int.add(1);
list_int.add(7);
list_int.add(9);
...
list_int.add(48);

public class Student
{
public int id{set;get;}//编号
public int class{set;get;}//班级
public string name{set;get;}//姓名
...
}
List<Student> list_student=new List<Student>();//学生
list_student.add(new Student{id=1,class=1,name="name1"});
list_student.add(new Student{id=2,class=1,name="name2"});
list_student.add(new Student{id=3,class=2,name="name3"});
...
list_student.add(new Student{id=50000,class=48,name="name50000"});

方法1:使用linq效率非常低,程序假死
var list=from s in list_student
where (from c in list_class select c.id).contains(s.class)
select s;

方法2:循环list_class,把已知班级id组合成字符串str_class,通过indexOf()判断学生所在班级是否存在str_class中
string str_class=",";
foreach(int i in list_class)
str_class+=i+",";
var list=from s in list_student
where str_class.indexOf(","+s.class+",")>=0
select s;

...全文
867 13 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
13 条回复
切换为时间正序
请发表友善的回复…
发表回复
EIT王子 2019-04-29
  • 打赏
  • 举报
回复
引用 12 楼 MisterDotNet 的回复:
var list_serAll = from o in list_serviceAll
from l in list_ser_id
where l.id == o.id
select o;

这段代码是返回 list_serviceAll中课程id存在list_ser_id中的数据


你这有两个from了
MisterDotNet 2015-07-17
  • 打赏
  • 举报
回复
var list_serAll = from o in list_serviceAll
                         from l in list_ser_id
                         where l.id == o.id
                         select o;
这段代码是返回 list_serviceAll中课程id存在list_ser_id中的数据
MisterDotNet 2015-07-17
  • 打赏
  • 举报
回复
引用 8 楼 starfd 的回复:
var list=from s in list_student
from c in list_class
where c.id == s.classid
select s;

为什么你要写成那样?而不是这样?




var list_serAll = from o in list_serviceAll
from l in list_ser_id
where l.id == o.id
select o;


上面是我的代码,用这段代码执行的时候程序也是假死,请问为什么?
ajianchina 2015-07-17
  • 打赏
  • 举报
回复
引用 9 楼 MisterDotNet 的回复:
老师,我的错,我只是举得一个例子,list_class 存储班级对象,对象有个属性id表示班级id
不要称什么老师了,我懂的不多,我刚刚帮你进行过测试 用用了关键字class,我改名classs了 按这样的查询,得出list结果是8毫秒 var list = (from s in list_student where list_class.Contains(s.classs) select s).ToList(); 第二条语句查询得出list结果是320毫秒 string str_class = ","; foreach (int i in list_class) { str_class += i + ","; } var lists = (from s in list_student where str_class.IndexOf("," + s.classs + ",") >= 0 select s).ToList();
MisterDotNet 2015-07-17
  • 打赏
  • 举报
回复
引用 7 楼 ajianchina 的回复:
你的list_class是List<int> 怎么会select出来id呢,其实你from c in list_class select c这段也本该是多余的,这段查询可以省掉,可以这样子 var list=from s in list_student where list_class.Contains(s.class) select s; 如果 list.ToList()的话得出结果应该可以控制在10毫秒左右,就你的50000条记录而言。
老师,我的错,我只是举得一个例子,list_class 存储班级对象,对象有个属性id表示班级id
  • 打赏
  • 举报
回复
var list=from s in list_student
                     from c in list_class
              where c.id == s.classid
              select s;
为什么你要写成那样?而不是这样?
ajianchina 2015-07-17
  • 打赏
  • 举报
回复
你的list_class是List<int> 怎么会select出来id呢,其实你from c in list_class select c这段也本该是多余的,这段查询可以省掉,可以这样子 var list=from s in list_student where list_class.Contains(s.class) select s; 如果 list.ToList()的话得出结果应该可以控制在10毫秒左右,就你的50000条记录而言。
MisterDotNet 2015-07-17
  • 打赏
  • 举报
回复
引用 5 楼 ajianchina 的回复:
上面又发失败了 var list=from s in list_student where (from c in list_class select c.id).contains(s.class) select s;
老师,student对象里面的class属性是班级的id,不是班级对象啊
ajianchina 2015-07-16
  • 打赏
  • 举报
回复
上面又发失败了 var list=from s in list_student where (from c in list_class select c.id).contains(s.class) select s;
ajianchina 2015-07-16
  • 打赏
  • 举报
回复
既然要比较Contains跟IndexOf,就拿他原来的方法测 var list=from s in list_student where (from c in list_class select c<span style="color: #FF0000;">.id</span>).contains(s.class) select s; 这里的id去掉
ajianchina 2015-07-16
  • 打赏
  • 举报
回复
回过头居然看到你第一条语句居然存在一个错误

var list=from s in list_student
              where (from c in list_class select c.id).contains(s.class)
              select s;
这儿有id吗?你改过来,50000条数据肯定可以在100毫秒以内算完,应该可能只有你第二条语句的1/3时间。
showjim 2015-07-16
  • 打赏
  • 举报
回复
HashSet<int>或者BitArray
ajianchina 2015-07-16
  • 打赏
  • 举报
回复
你这样怎么好比较,完全是两种不同逻辑的查询 拿第二段代码,要比就这样比: where str_class.indexOf(","+s.class+",")>=0 跟 where str_class.Contains(","+s.class+",") 这样采用可比性 我曾经做过测试Contains效率要高于indexOf

62,244

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术交流专区
javascript云原生 企业社区
社区管理员
  • ASP.NET
  • .Net开发者社区
  • R小R
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

.NET 社区是一个围绕开源 .NET 的开放、热情、创新、包容的技术社区。社区致力于为广大 .NET 爱好者提供一个良好的知识共享、协同互助的 .NET 技术交流环境。我们尊重不同意见,支持健康理性的辩论和互动,反对歧视和攻击。

希望和大家一起共同营造一个活跃、友好的社区氛围。

试试用AI创作助手写篇文章吧