По сути, вы выполняете операцию JOIN.Существует 3 типа алгоритмов соединения общего пользования - вложенный цикл, хэш и слияние.В вашем коде используется алгоритм вложенных циклов, который кажется подходящим для таблиц размером 10 и 5, если только один или оба уже не отсортированы (в этом случае объединение слиянием может быть более подходящим).
Я могу 'Я не представляю, что это узкое место в любом реальном приложении, но, возможно, мы можем немного улучшить его с некоторыми допущениями.
- Давайте начнем с подъема переменных, чтобы они не были пересчитаны(JIT-оптимизатор, вероятно, сделает это автоматически, но это не помешает):
<code>
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;
}
}
}
- При условии, что rowValue является строкой, давайте используем приведение:
<code>
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;
}
}
}
- Поскольку мы никогда не снимаем флажок, и сравнение bool должно быть в среднем быстрее, чем сравнение строк:
<code>
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;
}
}
}
- Предполагая, что каждое значение флажка уникально, мыможет прекратить итерации, когда мы найдем результат:
<code>
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
}
}
}
- Поскольку у вас есть 10 строк и 5 флажков - мы должны обратить циклы вспять.Так как мы разрываем внутренний цикл, когда значение найдено, увеличение внутреннего цикла до 2 более эффективно:
<code>
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;
}
}
}
- Предполагая, что вам не нужны культурные или регистрозависимые сравнения,мы можем использовать OrdinalIgnoreCase:
<code>
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;
}
}
}
Это самое лучшее, что я могу сделать.Я был бы удивлен, если бы была какая-либо измеримая разница в таком маленьком наборе данных.Итак, вот что вы должны действительно сделать:
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);
, которое может быть немного медленнее, но много читаетлучше ИМО.