При запросе с помощью LINQ-to-XML лучше/эффективнее оставлять значения элементов в виде строк или преобразовывать их в правильный тип?

Я постоянно сталкиваюсь с этим при написании запросов с помощью LINQ-to-XML: свойство Value элемента XElement является строкой, но на самом деле данные могут быть целым числом, логическим значением и т. д.

Допустим, у меня есть предложение «где» в моем запросе, которое проверяет, соответствует ли идентификатор, хранящийся в XElement, локальной (целочисленной) переменной с именем «id». Есть два способа сделать это.

<сильный>1. Преобразовать "id" в строку

string idString = id.ToString();
IEnumerable<XElement> elements =
    from
        b in TableDictionary["bicycles"].Elements()
    where
        b.Element(_ns + "id").Value == idString
    select
        b;

<сильный>2. Преобразовать значение элемента в int

IEnumerable<XElement> elements =
    from
        b in TableDictionary["bicycles"].Elements()
    where
        int.Parse(b.Element(_ns + "id").Value) == id
    select
        b;

Мне нравится вариант 2, потому что он сравнивает правильный тип. Технически я мог бы увидеть сценарий, в котором преобразование десятичного или двойного числа в строку заставило бы меня сравнить «1.0» с «1» (что было бы неравным) с десятичным (1.0) с десятичным (1) (что было бы равно) . Хотя предложение where с участием десятичных знаков, вероятно, встречается довольно редко, я мог видеть OrderBy в десятичном столбце - в этом случае это было бы очень серьезной проблемой.

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

Итак, вы анализируете значения элементов неукоснительно или только при необходимости? Почему?

Спасибо!

ИЗМЕНИТЬ:

Я обнаружил гораздо менее громоздкий синтаксис для преобразования.

<сильный>3. Приведение элемента к типу int

IEnumerable<XElement> elements =
    from
        b in TableDictionary["bicycles"].Elements()
    where
        (int)b.Element(_ns + "id") == id
    select
        b;

Я думаю, что теперь это будет мой предпочтительный метод ... если кто-то не отговорит меня от него :)

РЕДАКТИРОВАНИЕ II:

После публикации моего вопроса мне пришло в голову, что: ЭТО XML. Если бы у меня действительно было достаточно данных, чтобы производительность была проблемой, я бы, вероятно, использовал настоящую базу данных. Итак, еще одна причина пойти на кастинг.


person devuxer    schedule 25.07.2009    source источник


Ответы (2)


Трудно оценить проблемы с производительностью без измерения. Но я думаю, что у вас есть два сценария.

  1. Если вам нужно использовать большую часть (или все) значений в выражении рано или поздно, то, вероятно, лучше заранее оплатить затраты ЦП на преобразование в собственные типы, отбрасывая строковые данные XML раньше.
  2. Если вы собираетесь касаться (оценивать или использовать) только несколько значений, то, скорее всего, будет дешевле с точки зрения процессорного времени лениво преобразовывать строковые данные в собственные типы - во время (или близко к нему временно) потребление.

Теперь это просто соображения процессорного времени. Я предполагаю, что сами данные, вероятно, будут занимать значительно меньше памяти после преобразования в собственные типы значений. Это позволяет раньше отказаться от строковых (XML) данных.

Короче говоря, на такие вопросы редко бывают черные или белые ответы: это будет зависеть от вашего сценария, сложности данных, количества имеющихся данных и когда они будут использоваться (касаться или оцениваться).

Обновлять

В комментарии Дэна к моему первоначальному ответу он просит об общем практическом правиле в тех случаях, когда нет времени или причин для проведения подробных измерений.

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

  1. Код уже будет сжигать некоторые ресурсы ЦП, ввода-вывода и памяти во время синтаксического анализа.
  2. Код, похоже, проще выполнять преобразования во время загрузки (а не в другое время), поскольку все это можно закодировать простым процедурным способом.
  3. Это, вероятно, будет более эффективным с точки зрения памяти.
  4. Когда данные необходимо использовать, они уже находятся в собственном формате - это будет намного лучше, чем работа со строковыми данными во время потребления: сравнения и вычисления с собственными типами обычно будут намного эффективнее, чем работа с данными в строковом формате. . Вероятно, это также упростит потребляющий код.

Опять же, я предлагаю это как эмпирическое правило :) Будут сценарии, в которых другой подход будет более оптимальным с точки зрения производительности или каким-то образом сделает код «лучше» (более целостным, модульным, простым в обслуживании, и т.д).

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

person Foredecker    schedule 25.07.2009
comment
Это отличный и вдумчивый ответ, но я думаю, что искал хорошее эмпирическое правило, поскольку у меня нет времени проводить много тестов производительности по моим запросам. Спасибо. - person devuxer; 26.07.2009

Я согласен с вашим вторым редактированием. Если производительность является проблемой, вы получите гораздо больше, используя более запрашиваемую структуру данных (или просто кэшируя словарь по идентификатору из вашего XML для повторных поисков), чем изменяя способ сравнения/анализа значений.

Тем не менее, я бы предпочел использовать различные явные переопределения приведения в XElement. Кроме того, если ваш идентификатор может когда-либо быть пустым (лучше перестраховаться, чем сожалеть), вы также можете сделать эффективное приведение к int?.

person dahlbyk    schedule 26.07.2009