Linq to Xml, сохранить загруженный XDocument?

#c# #.net #xml #linq #linq-to-xml

#c# #.net #xml #linq #linq-to-xml

Вопрос:

Допустим, я создаю программу WinForms, которая будет использовать XML-документ за кулисами в качестве механизма сохранения…

Каковы плюсы / минусы двух следующих подходов…

  1. Загружайте XDocument при каждом вызове метода:

     public class XmlFoosRepository
    {
        string xmlFileName;
    
        public XmlFoosRepository(string xmlFileName)
        {
            this.xmlFileName = xmlFileName;
        }
    
        public int AddFoo(Foo foo)
        {
            var xDoc = XDocument.Load(xmlFileName); // Always call Load()
    
            // ...
    
            xDoc.Save(xmlFileName);
            return foo.ID;
        }    
    
        public IEnumerableamp;<Fooamp;> GetFoos()
        {
            var xDoc = XDocument.Load(xmlFileName); // Always call Load()
    
            // ...
    
            return foos;
        }
    }
      

или

  1. Сохранить XDocument в памяти…

     public class XmlFoosRepository
    {
        XDocument xDoc;
    
        public XmlFoosRepository(string xmlFileName)
        {
            xDoc = XDocument.Load(xmlFileName); // Now in memory
        }
    
        public int AddFoo(Foo foo)
        {
            // ...
    
            xDoc.Save(xmlFileName);
            return foo.ID;
        }
    
        public IEnumerableamp;<Fooamp;> GetFoos()
        {
            // ...
    
            return foos;
        }
    }
      

Ответ №1:

Первый вариант просто кажется немного неэффективным, поскольку вы ничего не получаете, загружая XML-документ каждый раз, когда обращаетесь к нему. С вариантом 1 вы должны перейти на диск и загрузить XML-файл в память, прежде чем обращаться к нему. Обращение к диску — одна из самых дорогостоящих операций, которые вы можете выполнить на современном компьютере, и ее следует избегать, насколько это возможно.

При этом, если XML-файл настолько велик, что объем памяти невероятно велик, то вы можете захотеть загружать его только в течение небольшого промежутка времени. Однако, если объем памяти настолько велик, возможно, вам захочется рассмотреть другой способ сохранения данных, который не требует от вас одновременной загрузки всего документа для внесения изменений.

Ответ №2:

Баланс в основном между памятью и доступом к файловой системе — если вы собираетесь часто использовать документ в своем коде, вы не хотите взаимодействовать с файловой системой больше, чем вам хотелось бы… но если к нему редко обращаются и он огромен, вы можете не захотеть, чтобы объем памяти был ограничен.

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

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

Просто как одну точку данных — я использую второй шаблон на веб-сайте C # in Depth для исправлений и т.д., и он работает очень хорошо.

Комментарии:

1. О, Джон, почему ты не делаешь что-то более значимое вместо того, чтобы вмешиваться в работу скромных разработчиков кода на SO, таких как я. =)

2. Я рад, что вы указали на модель потоков, я даже не думал об этом! Кроме того, я не знал, что Джон Скит написал книгу по C #! Угадайте, что у меня в рождественском списке?

Ответ №3:

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

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

Тем не менее, вы определенно получаете выгоду от кэша; в зависимости от документа и того, как часто вы к нему обращаетесь, вам не придется повторно обрабатывать документ в XDocument . Если документы большие или вы обращаетесь к ним много раз, то вы экономите время обработки, поскольку вы сделали это один раз, и вам не придется делать это снова.

Ответ №4:

Плюсы на основе файлов: — Хорошо работает во всех процессах (если требуется) — Позволяет снизить текущие требования к памяти (если файл большой, например, более 10 мб) Минусы на основе файлов: — Медленнее загружается при каждой операции

Плюсы на основе памяти: — Быстрее, нет накладных расходов на повторную сериализацию снова и снова — Проще переносить, если вам понадобится получить доступ к файлу позже через веб-службу и т.д. Недостатки, связанные с памятью: — Текущие требования к памяти (при большом файле)

Еще одна мысль: если у вас уже есть ваши данные в XML, почему бы просто не использовать их в качестве объектов POCO, вместо того, чтобы повторно сериализовать их в объекты в вашем методе «GetFoos».