1 前言
有些同学会觉得循环有不怎么耗时,从数据库取数据才耗时很长。那么旭东接下来让你知道就算是循环也可能会耗时很长的。
List<T_UserInfo> userList=new T_UserDAL().GetAll();//2000条数据
List<T_LoginLogInfo> loginLogList=new T_LoginLogDAL().GetAll();//20000条数据
foreach(var userInfo in userList){
var userLoginLogList=loginLogList.Where(o=>o.UserInfoID=userInfo.UserInfoID).ToList();
}
我们碰到这样一个情况要筛出每个用户的登陆日志信息。但是用户也就是userLIst有2000条数据,登陆日志信息有20000条数据。哪怕用LINQ筛选也会耗时很长,比如说一个用户筛选要4毫米,那么2000个用户就要8秒才能筛选完成。
说到这里,循环结构优化还是很有必要的。
2 循环+LINQ优化
碰到这种在循环中使用LINQ筛选数据的情况,想要进行性能优化的唯一办法就是减少使用LINQ进行筛选的数据的数据量。同样是用LINQ筛选数据,1000条数据筛选和20000条数据来进行筛选的情况下,1000条数据的用时明显会少很多。
List<T_UserInfo> userList = new T_UserDAL().GetAll();//2000条数据
List<T_LoginLogInfo> loginLogList = new T_LoginLogDAL().GetAll();//20000条数据
int batchSize = 100;
for (int i = 0; i < userList.Count / batchSize + 1; i++){//分批筛选
var itemUserList = userList.Skip(i * batchSize).Take(batchSize).ToList();
var itemLoginLogList = loginLogList.Where(o=>userList.Select(p=>p.UserInfoID).Contains(o.UserInfoID)).ToList();
foreach(var userInfo in itemUserList){//用户
var userLoginLogList = itemLoginLogList.Where(o=>o.UserInfoID == userInfo.UserInfoID).ToList();
}
}
既然这样我们可以使用两层循环来进行筛选,第一层循环因为数据量很大筛选会耗费很多时间但是循环次数会少很多,第二层循环虽然循环次数会很多但是因为筛选的数据量少耗时不会很多。用上面优化过后的代码来举例,第一层循环循环一次要6毫米,但是只有20次,那么第一层循环只有120毫米,而第二层循环循环一次要2毫米,2000次循环下来第二层循环耗时4秒,那么总的耗时为4.12秒会比改进之前的8秒耗时还是会快很多。
当然具体能快多少还是要看batchSize设置为多少才耗时最少。