1

考虑以下代码片段

列出 orderList ; // 这个列表是预先填充的

foreach (System.Web.UI.WebControls.ListItem item in OrdersChoiceList.Items) // OrdersChoiceList is of type System.Web.UI.WebControls.CheckBoxList
{
     foreach (Order o in orderList)
     {
           if (item.id == o.id)
           {
               item.Selected = scopeComputer.SelectedBox;
               break;
           }
     }
}

列表中有数千个项目,因此这些循环非常耗时。我们如何优化它?

此外,我们如何使用 LINQ 做同样的事情。我尝试使用连接操作,但无法根据“SelectedBox”设置“Selected”变量的值。现在我将 select 子句中的值硬编码为“true”,我们如何在 select 子句中传递和使用 SelectedBox 值

                 var v = (from c in ComputersChoiceList.Items.Cast<ListItem>()
                                    join s in scopeComputers on c.Text equals s.CName
                                        select c).Select(x=>x.Selected = true);
4

1 回答 1

3

我认为您需要消除嵌套迭代。正如您所说,两个列表都有大量项目。如果它们都有 5,000 个项目,那么在最坏的情况下您将看到 25,000,000 次迭代。

没有必要orderList为每一个ListItem. 而是创建一个 ID 查找,以便您对每个 ID 进行快速 O(1) 查找。不确定 hit 涉及到什么工作scopeComputer.SelectedBox,但也可以在循环之外解决。

bool selectedState = scopeComputer.SelectedBox;
HashSet<int> orderIDs = new HashSet<int>(orders.Select(o => o.id));

foreach (System.Web.UI.WebControls.ListItem item in OrdersChoiceList.Items)
{
    if (orderIDs.Contains(item.id))
        item.Selected = selectedState;
}

使用HashSet查找,您现在实际上只需要迭代 5,000 次以及超快速查找。

编辑:据我所知, 上没有id属性ListItem,但我假设您发布的代码为简洁起见进行了压缩,但在很大程度上代表了您的整个过程。我将保留我的代码 API/用法以匹配您那里的内容;我假设它可以翻译回您的具体实现。

编辑:根据您编辑的问题,我认为您正在对检索参考进行另一次查找/迭代。scopeComputer同样,您可以对此进行另一次查找:

HashSet<int> orderIDs = new HashSet<int>(orders.Select(o => o.id));
Dictionary<string, bool> scopeComputersSelectedState = 
    scopeComputers.ToDictionary(s => s.CName, s => s.Selected);

foreach (System.Web.UI.WebControls.ListItem item in OrdersChoiceList.Items)
{
    if (orderIDs.Contains(item.id))
        item.Selected = scopeComputersSelectedState[item.Text];
}

同样,不确定您拥有的确切类型/用途。您也可以使用单个 LINQ 查询将其压缩,但我认为(就性能而言)您不会看到很大的改进。我还假设ScopeComputer每个条目都有一个匹配项,ListItem.Text否则在访问scopeComputersSelectedState[item.Text]. 如果不是,那么将其更改为执行TryGetValue查找应该是一个简单的练习。

于 2013-07-25T13:02:45.457 回答