什么是给定代码的优化版本?

时间:2011-02-19 13:23:14

标签: c# asp.net linq lambda checkbox

我有一个代码块,我在检查复选框,比较给定代码中数据表的内容:

 foreach (DataRow dr in dtResult.Rows)
 {
    for (var i = 0; i < chkboxListWorkTypes.Items.Count; i++)
    {
      if (chkboxListWorkTypes.Items[i].Value.Equals(dr["WorkTypeID"].ToString()))
      {
         chkboxListWorkTypes.Items[i].Selected = true;
      }
    }
 }

任何labmda或linq表达都会很棒。

4 个答案:

答案 0 :(得分:2)

真正的优化将是数据绑定。

答案 1 :(得分:1)

这就是我的工作

 foreach (DataRow dr in dtResult.Rows)
 {
    string cWorkTypeID = dr["WorkTypeID"].ToString();
    for (var i = 0; i < chkboxListWorkTypes.Items.Count; i++)
    {
         if(chkboxListWorkTypes.Items[i].Value.Equals(cWorkTypeID))
           chkboxListWorkTypes.Items[i].Selected =true;
    }
 }

如果复选框上的ID不同(可能是),

 foreach (DataRow dr in dtResult.Rows)
 {
    string cWorkTypeID = dr["WorkTypeID"].ToString();
    for (var i = 0; i < chkboxListWorkTypes.Items.Count; i++)
    {
         if(chkboxListWorkTypes.Items[i].Value.Equals(cWorkTypeID))
         {
            chkboxListWorkTypes.Items[i].Selected = true;
            break;
         }
    }
 }

答案 2 :(得分:0)

尽管它与@Aristos的回答几乎完全相同,但是按照以下方式执行此操作会将您的代码行减少一些:

foreach (DataRow dr in dtResult.Rows)
{
    ListItem item = chkboxListWorkTypes.Items.FindByValue(dr["WorkTypeID"].ToString());
    if (item != null)
    {
         item.Selected = true;
    }
}

答案 3 :(得分:0)

您实际上是在执行JOIN操作。常用3 types of join algorithms - 嵌套循环,哈希和合并。您的代码使用嵌套循环算法 - 这似乎适用于10和5的表大小,除非一个或两个已经排序(在这种情况下,合并连接可能更合适)。

我无法想象这是任何实际应用程序中的瓶颈 - 但是,我们可以通过一些假设来改进它。

  1. 让我们从提升变量开始,以确保它们不会被重新计算(JIT优化器可能会自动执行此操作,但它不会受到影响):
    
     int chkBoxCount = chkboxListWorkTypes.Items.Count;
     foreach (DataRow dr in dtResult.Rows)
     {
        string rowValue = dr["WorkTypeID"].ToString();
        for (var i = 0; i < chkBoxCount; i++)
        {
          var chkBox = chkboxListWorkTypes.Items[i];
          if (chkBox.Value.Equals(rowValue))
          {
             chkBox.Selected = true;
          }
        }
     }
    
  2. 假设rowValue是一个字符串,让我们使用一个强制转换:
    
     int chkBoxCount = chkboxListWorkTypes.Items.Count;
     foreach (DataRow dr in dtResult.Rows)
     {
        string rowValue = (string)dr["WorkTypeID"];
        for (var i = 0; i < chkBoxCount; i++)
        {
          var chkBox = chkboxListWorkTypes.Items[i];
          if (chkBox.Value.Equals(rowValue))
          {
             chkBox.Selected = true;
          }
        }
     }
    
  3. 由于我们永远不会取消选中复选框,因此bool比较应该比字符串比较更快:
    
     int chkBoxCount = chkboxListWorkTypes.Items.Count;
     foreach (DataRow dr in dtResult.Rows)
     {
        string rowValue = (string)dr["WorkTypeID"];
        for (var i = 0; i < chkBoxCount; i++)
        {
          var chkBox = chkboxListWorkTypes.Items[i];
          if (!chkBox.Selected && chkBox.Value.Equals(rowValue)) 
          {
             chkBox.Selected = true;
          }
        }
     }
    
  4. 假设每个复选框值都是唯一的,我们可以在找到结果时停止迭代:
    
     int chkBoxCount = chkboxListWorkTypes.Items.Count;
     foreach (DataRow dr in dtResult.Rows)
     {
        string rowValue = (string)dr["WorkTypeID"];
        for (var i = 0; i < chkBoxCount; i++)
        {
          var chkBox = chkboxListWorkTypes.Items[i];
          if (!chkBox.Selected && chkBox.Value.Equals(rowValue)) 
          {
             chkBox.Selected = true;
             break; // stop looking
          }
        }
     }
    
  5. 由于你有10行和5个复选框 - 我们应该反转循环。由于我们在找到值时在内部循环上中断,因此使内部循环中的较大者更有效:
    
     int chkBoxCount = chkboxListWorkTypes.Items.Count;
     for (var i = 0; i < chkBoxCount; i++)
     {
       var chkBox = chkboxListWorkTypes.Items[i];
       if (chkBox.Selected) continue;
       foreach (DataRow dr in dtResult.Rows)
       {
          string rowValue = (string)dr["WorkTypeID"];
          if (chkBox.Value.Equals(rowValue)) 
          {
             chkBox.Selected = true;
             break;
          }
       }
     }
    
  6. 假设您不关心文化或区分大小写的比较,我们可以使用OrdinalIgnoreCase:
    
     int chkBoxCount = chkboxListWorkTypes.Items.Count;
     for (var i = 0; i < chkBoxCount; i++)
     {
       var chkBox = chkboxListWorkTypes.Items[i];
       if (chkBox.Selected) continue;
       foreach (DataRow dr in dtResult.Rows)
       {
          string rowValue = (string)dr["WorkTypeID"];
          if (string.Equals(chkBox.Value, rowValue, StringComparison.OrdinalIgnoreCase)) 
          {
             chkBox.Selected = true;
             break;
          }
       }
     }
    
  7. 这是我能做的最好的事情。如果在如此小的数据集上存在任何可测量的差异,我会感到惊讶。所以,这就是真正做的事情:

     var workTypeIds = dtResult.Rows.Cast<DataRow>().Select(dr => (string)dr["WorkTypeId"]);
     foreach (var chk in chkBoxListWorkTypes) 
     {
         if (workTypeIds.Contains(chk.Value))
         {
            chk.Selected = true;
         }
     }    
    

    或者,每个分机:

     var workTypeIds = dtResult.Rows.Cast<DataRow>().Select(dr => (string)dr["WorkTypeId"]);
     chkBoxListWorkTypes.Where(c => workTypeIds.Contains(c.Value)).Each(c => c.Selected = true);
    

    这可能会稍微慢一些,但IMO读得好多了。