【问题标题】:Code Optimization to check some items of checkbox list检查复选框列表的某些项目的代码优化
【发布时间】:2013-07-25 12:45:49
【问题描述】:

考虑下面的代码 sn-p

列出 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);

【问题讨论】:

  • 我们可以在这里使用 LINQ 吗?
  • 也许 if(OrdersChoiceList.Items.Select(i => i.id).Intersect( orderList.Select(i => i.id) ).Any()) ...
  • 感觉即使迭代“数千个项目”来更新它们的选定状态也不应该花很长时间。我感觉“耗时”方面是 GUI 层自行更新。编辑:哦,也许不是。没有在这里找到嵌套的 foreach 循环。绝对将您的 orderList 更改为某种查找表,而不是为每个 ListItem 一次又一次地重新迭代它。
  • 两个列表中是否有数千个项目?还是一个列表中有数千个,而另一个列表中则少得多?
  • 两个列表都有大项目。

标签: c# asp.net performance linq


【解决方案1】:

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

无需为每个ListItem 不断重复orderList。而是创建一个 ID 查找,以便您对每个 ID 进行快速 O(1) 查找。不确定点击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 次加上超快速查找。

编辑:据我所知,ListItem 上没有id 属性,但我假设您发布的代码为简洁起见,但在很大程度上代表了您的整个流程。我将保留我的代码 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 查询将其压缩,但我认为(就性能而言)您不会看到很大的改进。我还假设每个ListItem.Text 条目都有一个匹配的ScopeComputer,否则访问scopeComputersSelectedState[item.Text] 时会出现异常。如果没有,那么将其更改为执行TryGetValue 查找应该是一个简单的练习。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-12-02
    • 1970-01-01
    • 2014-06-25
    • 2011-07-20
    • 1970-01-01
    相关资源
    最近更新 更多