今天是圣诞节耶!jingle bell jingle bell .....
上周遇到一个问题,用list集合removeall方法去除满足条件的数据,结果那真是有点慢,慢的我都自惭形秽了,本以为可以翘着二郎腿,结束任务,结果出现这大的问题,吓得我立马放下腿。
一查发现万级的数据中过滤万级左右数据,嗯,这也是第一次碰到,没经验,不知者无过。在我努力的结晶下,结果还是满意的。
真相就是用HaseSet的contains 过滤代替list的removeall条件过滤,为什么呢,那就要看源码是如何实现的了。
所以今天就来传授经验,接招。
两种方法做对比。时间是多次执行取的平均值,保证有效性,从统计表中可以看到,数据量越大,差异越明显。
数据量 | 过滤量 | list过滤所用time(ms) | hashse过滤所用time(ms) |
10 | 5 | 1左右 | 1左右 |
100 | 50 | 1左右 有时候2 | 1左右 |
1000 | 500 | 18左右 | 1左右 有时候2 |
10000 | 5000 | 1650左右 | 2~4左右 |
100000 | 50000 | 195439左右 | 30左右 |
10w的数据量过滤所用时间:
所以你知道当时有多慢了吧。
测试demo,主要代码:
public List<Model> GetResultHashData(List<Model> alllist, HashSet<Model> filterlist) { List<Model> molist = new List<Model>(); foreach (var item in alllist) { if (!filterlist.Contains(item)) { molist.Add(item); } } return molist; }
注意的是,model要重写getHashCode以及Equeals,不重写就没有过滤效果
原因就是默认比较的是值,在比较其他自定义对象时就是比较引用地址。重写之后目的就是比较两个对象的value值是否相等
http://blog.csdn.net/basycia/article/details/52081111 有详细解释
public class Model { public int Id { get; set; } public string Name { get; set; } public string Desc { get; set; } public override int GetHashCode() { return this.Id; } public override bool Equals(object obj) { Model md = (Model)obj; return md.Id==this.Id&&md.Name==this.Name&&md.Desc==this.Desc; } }
你没看错,灵魂代码就几行,就是这么的简单。
嗯,下班了