Вопрос по .net, dictionary, switch-statement – .NET: переключение против словаря для строковых ключей

11

У меня возникла ситуация, когда у меня есть бизнес-объект с примерно 15 свойствами разных типов. Бизнес-объект также должен реализовывать интерфейс, который имеет следующий метод:

object GetFieldValue(string FieldName);

Я вижу 2 способа реализации этого метода:

Используйте оператор switch:

switch ( FieldName )
{
    case "Field1": return this.Field1;
    case "Field2": return this.Field2;
    // etc.
}

Используйте словарь (SortedDictionary или HashTable?):

return this.AllFields[FieldName];

Что будет более эффективным?

Добавлено: Забыл сказать. Этот метод предназначен для отображения элемента в сетке. Сетка будет иметь столбец для каждого из этих свойств. Обычно будут сетки с более чем 1000 элементов в них. Тот'почему яЯ обеспокоен производительностью.

Добавлено 2:

Вот'Идея: гибридный подход. Создайте статический словарь, в котором ключами будут имена свойств, а значениями - индексы в массиве. Словарь заполняется только один раз, при запуске приложения. Каждый экземпляр объекта имеет массив. Итак, поиск будет выглядеть так:

return this.ValueArray[StaticDictionary[FieldName]];

Алгоритм заполнения словаря может использовать отражение. Затем сами свойства будут реализованы соответствующим образом:

public bool Field1
{
    get
    {
        object o = this.ValueArray[StaticDictionary["Field1"]]; 
        return o == null ? false : (bool)o;
    }
    set
    {
        this.ValueArray[StaticDictionary["Field1"]] = value;
    }
}

Кто-нибудь может увидеть какие-либо проблемы с этим?

Это также может быть сделано на один шаг вперед, и ValueArray / StaticDictionary можно поместить в отдельный универсальный типValueCollection, гдеT указал бы тип для отражения. ValueCollection также будет обрабатывать случай, когда еще не установлено значение. Свойства могут тогда быть написаны просто как:

public bool Field1
{
    get
    {
        return (bool)this.Values["Field1"];
    }
    set
    {
        this.Values["Field1"] = value;
    }
}

И, в конце концов, яЯ снова начинаю задумываться, не может ли простой оператор switch быть быстрее и проще в обслуживании ....

Честно говоря, этоЭто список DevExpress TreeList. Это'Это как гибрид дерева / сетки. Таким образом, данные должны быть иерархическими. И интерфейс там, чтобы TreeList понимал иерархиюN вещи. Я мог бы, вероятно, также перевести все это в DataTable (оно также может связываться с этим), но потом мне будет удобнее работать. Vilx-
не должен»это будет медленнее, чем любой из них? Vilx-
Есть ли причина, по которой выне привязывает весь объект к сетке как дата? Rowland Shaw

Ваш Ответ

4   ответа
21
switch:      good efficiency, least maintainable
dictionary:  good efficiency, better maintainability
reflection:  least efficient, best maintainability

Подсказка: игнорируйте эффективность и заботьтесь только о ремонтопригодности, если только вы неЯ проверил производительность и обнаружил, что это проблема.

Я не говорю, что отражение - это ваш единственный выбор, просто оно позволит вам добавлять / удалять и переименовывать свойства по мере необходимости, и не нужно синхронизировать оператор switch или словарь.

@ Vilx, ваш гибридный подход будет работать в теории, но выабсолютно правы в отношении дополнительных проблем, связанных с ремонтопригодностью. Я'Вероятно, я бы выбрал простой словарь или метод переключения. Гибридный подход будет начинатьизобретать велосипед " в этих других рамках (CSLA) делают для вас такие вещи. Ash
@ Vilx, как яМне комфортно с Reflection, яПросто сравните его со словарем или переключателем (используя класс секундомера), а затем решите. Да, 15 000 обращений к версии GetFieldValue (), которая использует отражение, могут быть проблемой производительности, но вам нужно подтвердить это. Ash
@ Грег, хорошая мысль. Отражение неТяжело, тебе просто нужно познакомиться с генераломдерево объектов " и как ориентироваться. Однако я делаю код отражения в классы атрибутов-помощников, которые затем можно использовать, просто добавляя атрибуты в свой код. Ash
Словарь более эффективен, чем оператор switch? Я не'не ожидал этого, не могли бы вы уточнить? Bubblewrap
0

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

Позвольте мне привести вам пример:скажем, у вас есть следующая реализация:

private string _latestFieldName = string.Empty;
private PropertyInfo _propertyInfo;

object GetFieldValue(string FieldName)
{
  if(FieldName != _latestFieldName)
  {
    _propertyInfo = typeof(yourTypeName).GetProperty(FieldName);
  }
  return _propertyInfo.GetValue(this,null);
}

Если ваш рендеринг сетки отображает строку за один раз с использованием отражения, он должен будет каждый раз получать информацию о недвижимости. Когда вы рендерите столбец за столбцом, вы 'Я должен получить propertyInfo только один раз для каждого свойства, и так как прогноз ветвления будет правильным почти каждый раз, когда вы 'Я пропустил только несколько тактов на if. Когда у вас уже есть PropertyInfo, и вы неНужно привести результат вызова к GetValue. использование отражения ОЧЕНЬ близко к использованию метода получения свойства, когда дело касается скорости.

Моя точка зрения, прежде чем вы начнете оптимизировать, используйте профилировщик. (Конечно, если вы можетеизменить сетку хорошо, вы не можетеи правда не оптимизирую)

Нет, я могуизменить сетку. :) Vilx-
7

Потому что вы используете строки словарь, вероятно, будет быстрее. Switch будет по существу переведен в хеш-таблицу при использовании строк. Но если вы используете целые числа или что-то подобное, оно будет переведено в таблицу переходов и будет быстрее.

увидетьэтот ответ и вопрос для более подробной информации

Лучше всего профилировать и найти наверняка

0

Switch фактически имеет 2 преимущества по сравнению со словарем:

  1. Вы можете создать настроенное сообщение об исключении в разделе по умолчанию, которое может содержать недопустимое значение. В случае словаря вы получаете только исключение KeyNotFoundException, которое нет содержит ключевое имя.
  2. Вы можете обрабатывать нулевые значения. Словарь можетне хранить ноль в качестве ключа.

Похожие вопросы