Оптимизирован ли метод, который я использую для поиска в моем общем списке? - PullRequest
1 голос
/ 07 июня 2010

В какой-то момент будет большое количество записей, около 50 000.Имея это в виду, метод GetEquipmentRecord соответствует задаче.спасибо за ваши мнения.

c #, net 2,0

public enum EquipShift { day, night };

public class EquipStatusList : List<EquipStatus>
{
    string SerialFormat = "yyyyMMdd";

    int _EquipmentID;
    string _DateSerial;
    EquipShift _Shift;

    public EquipStatus GetEquipmentRecord(int equipmentID, EquipShift shift, 
                                            DateTime date)
    {
        _DateSerial = date.ToString(SerialFormat);
        _Shift = shift;
        _EquipmentID = equipmentID;

        return this.Find(checkforEquipRecord);
    }

    bool checkforEquipRecord(EquipStatus equip)
    {
        if ((equip.EquipmentID == _EquipmentID)
              && (equip.Shift == _Shift) 
              && (equip.Date.ToString(SerialFormat) == _DateSerial))
            return true;
        else
            return false;
    }
}

обновление: я изменил оценку, чтобы прочитать

           if ((equip.Date.Date == _date.Date) &&  (equip.EquipmentID == _EquipmentID) && (equip.Shift == _Shift)  )

не уверен, что это помогает

Ответы [ 4 ]

3 голосов
/ 07 июня 2010

Не комментируя ваш выбор алгоритма, мы можем сказать, что он, вероятно, достаточно оптимизирован .

У вас есть O (n) find() там;поиск отсортированного списка с помощью двоичного поиска будет O (lg n), а поиск хэш-набора (или словарь в C # 2.0) будет, например, O (1).Hash-set, очевидно, был бы подходящим вариантом, если бы вы часто вызывали эту функцию.

Но узкие места редко бывают там, где вы ожидаете их, поэтому вы задаете вопрос об этом конкретном средствечто, в конечном счете, профилирование позже фактически покажет, что большие замедления в другом месте.

0 голосов
/ 07 июня 2010

Ну, очевидный способ улучшить ваш checkForEquipRecord метод - это изменить

if ((equip.Date.Date == _date.Date) &&  (equip.EquipmentID == _EquipmentID) && (equip.Shift == _Shift)  )
    return true;
else
    return false;

до return (equip.Date.Date == _date.Date) && (equip.EquipmentID == _EquipmentID) && (equip.Shift == _Shift)

Что касается эффективности, это может быть уже оптимизация, которую выполняет JIT-компилятор.

0 голосов
/ 07 июня 2010

Нет, это не так. Вся ваша конструкция не может быть использована в многозадачной среде. Вы сохраняете детали для поиска в качестве экземпляров класса. Я бы воспользовался PLINQ (Parallel Linq) и обычными операторами, также я бы не стал использовать сам список, но предложил бы такой метод расширения:

public static EquipStatus GetEquipmentRecord(this IEnumerable<EquipStatus> list, int equipmentID, EquipShift shift, DateTime date)
{
  return list.AsParallel().FirstOrDefault(e => e.EquipmentID == equipmentID && e.Shift == shift, e.Date.Date == date.Date);
}

При этом возможен одновременный поиск нескольких раз.

0 голосов
/ 07 июня 2010

Вы можете значительно ускорить это, внедрив подходящий метод GetHashCode и используя System.Collections.Generic.HashSet<EquipStatus> в качестве контейнера-носителя. Однако, так как не совсем понятно, как вы используете свой класс (то есть какие другие List<T> методы вы используете), ymmv.

...