【问题标题】:Filtering big collection过滤大集合
【发布时间】:2017-05-26 12:31:50
【问题描述】:

我在 3000 名员工周围循环,每个员工在一个月的所有日期循环。

我已经从 Db 预加载了一个列表 ShiftDetails 以提高性能。

foreach (var item in lstEmp)
{
  while (fDate <= ToDate)
  {
    var employeeShifts = ShiftDetails
      .Where(a => a.EmployeeId == item.Id && a.ShiftDate == fDate)
      .Select(a => a)
      .FirstOrDefault();
  }
}

当我使用 Profiler 检查性能时,上面的代码行占用了大量时间。

有什么方法可以提高代码的性能?

我已经搜索并发现字典最适合解决这个问题,但它们应该有唯一的键,在我的情况下,我在列表中没有任何唯一的列。

【问题讨论】:

  • 您可以使用Parallel.Foreach 方法加快速度吗?
  • 您多久增加一次fDate 变量?是DateTime 对象还是某个时间戳?每毫秒迭代可能比 LINQ 到 3000 个对象更痛苦
  • 它是 DateTime 对象,对于它迭代一个月的每个员工,例如4 月 1 日至 4 月 30 日。

标签: c# performance linq asp.net-mvc-4


【解决方案1】:

据我所知,EmployeeId 和 ShiftDate 的组合可能是您的唯一键。

尝试使用类似这样的方式手动创建密钥:

var key = EmployeeId.ToString() + " - " + a.ShiftDate.ToString();

那么您的搜索将只是这样的一行:

if (myDictionary.ContainsKey(key))
{
//  .. do your logic here
}

【讨论】:

    【解决方案2】:

    这个解决方案怎么样:

    foreach (var item in lstEmp)
    {
      var employeeShifts = ShiftDetails
          .Where(a => a.EmployeeId == item.Id && isInDate(a.ShiftDate))
          .Select(a => a)
          .FirstOrDefault();
    }
    

    在代码中的任何其他地方:

    public bool isInDate(date start, date end, date dateFromUserProperty){
        //if dateFromUserProperty is within the range (start - end date) return true, 
        //else return false
    }
    

    你能解释一下什么是物品吗?您是否试图在项目集合和用户集合之间找到交集?

    【讨论】:

      【解决方案3】:

      我会将您的操作分为两个程序:

      • 按班次过滤每个EmployeeId

      • 给定过滤后的班次,先过滤ShiftDate


      在 while 循环外按EmployeeId 过滤更快,因为我们只计算一次这个结果,而不是每月的每个日期。将结果保存为List 也给我们带来了轻微的性能提升,因为我们可以使用List.Find(它返回给定谓词的第一个匹配值,并针对Lists 进行了优化)而不是Where/@ 987654328@.

      foreach (var item in lstEmp)
      {
          var shiftsByEmployeeId = ShiftDetails.Where(a => a.EmployeeId == item.Id).ToList();
          while (fDate <= ToDate)
          {
              var employeeShifts = shiftsByEmployeeId.Find(a => a.ShiftDate == fDate);
          }
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2018-05-07
        • 2014-03-12
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-03-22
        相关资源
        最近更新 更多