Эффективность десериализации против XmlReader - PullRequest
2 голосов
/ 12 октября 2009

Я работаю со сложной XML-схемой, для которой я создал структуру класса, используя xsd.exe (с некоторыми усилиями). Теперь я могу надежно десериализовать XML в сгенерированную структуру класса. Например, рассмотрим следующий XML-код из веб-службы:

<ODM FileType="Snapshot" CreationDateTime="2009-10-09T19:58:46.5967434Z" ODMVersion="1.3.0" SourceSystem="XXX" SourceSystemVersion="999">
  <Study OID="2">
    <GlobalVariables>
      <StudyName>Test1</StudyName>
      <StudyDescription/>
      <ProtocolName>Test0001</ProtocolName>
    </GlobalVariables>
    <MetaDataVersion OID="1" Name="Base Version" Description=""/>
    <MetaDataVersion OID="2" Name="Test0001" Description=""/>
    <MetaDataVersion OID="3" Name="Test0002" Description=""/>
  </Study>
</ODM>

Я могу десериализовать XML следующим образом:

public ODMcomplexTypeDefinitionStudy GetStudy(string studyId)
{
  ODMcomplexTypeDefinitionStudy study = null;
  ODM odm = Deserialize<ODM>(Service.GetStudy(studyId));
  if (odm.Study.Length > 0)
    study = odm.Study[0];
  return study;
}

Service.GetStudy () возвращает поток HTTPResponse из веб-службы. А Deserialize () - это вспомогательный метод, который десериализует поток в тип объекта T.

У меня такой вопрос: эффективнее ли процесс десериализации создать всю структуру класса и десериализовать xml, или эффективнее захватить только интересующий xml и десериализовать этот xml. Например, я мог бы заменить приведенный выше код на:

public ODMcomplexTypeDefinitionStudy GetStudy(string studyId)
{
  ODMcomplexTypeDefinitionStudy study = null;
  using (XmlReader reader = XmlReader.Create(Service.GetStudy(studyId)))
  {
    XDocument xdoc = XDocument.Load(reader);
    XNamespace odmns = xdoc.Root.Name.Namespace;
    XElement elStudy = xdoc.Root.Element(odmns + "Study");
    study = Deserialize<ODMcomplexTypeDefinitionStudy>(elStudy.ToString());
  }
return study;
}

Я подозреваю, что первый подход предпочтительнее - во втором примере много манипуляций с dom, и процесс десериализации должен иметь оптимизацию; однако что происходит, когда xml резко растет? Допустим, источник возвращает 1 МБ xml, и я действительно заинтересован только в очень маленьком компоненте этого xml. Должен ли я позволить процессу десериализации заполнить содержащий класс ODM всеми его массивами и свойствами дочерних узлов? Или просто найдите дочерний узел, как во втором примере !! ??

Не уверен, что это помогает, но вот краткий обзор этой дилеммы:

alt text

Ответы [ 2 ]

1 голос
/ 12 октября 2009

Brett

Более поздние версии .net будут создавать пользовательские сборки сериализатора. Нажмите на свойства проекта -> построить и найдите «Создать сборки сериализации» и измените на Вкл. Десериализатор XML будет использовать эти сборки, которые настроены для классов в вашем проекте. Они намного быстрее и менее ресурсоемки, поскольку рефлексия не задействована.

Я бы пошел по этому пути, чтобы при изменении класса вам не приходилось беспокоиться о проблемах сериализации. Производительность не должна быть проблемой.

0 голосов
/ 12 октября 2009

Я рекомендую вам не предоптимизировать. Если ваш код работает, используйте его как есть. Продолжайте работать над кодом, который не завершен или не работает.

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

...