Злоупотребление XmlReader ReadSubtree () - PullRequest
4 голосов
/ 22 сентября 2008

Мне нужно проанализировать xml-файл, который практически является изображением действительно большой древовидной структуры, поэтому я использую класс XmlReader для заполнения дерева «на лету». Каждому узлу передается только тот кусок XML, который он ожидает от своего родителя через функцию ReadSubtree (). Преимущество этого состоит в том, что вам не нужно беспокоиться о том, когда узел использует все свои дочерние элементы. Но теперь мне интересно, действительно ли это хорошая идея, поскольку может быть тысячи узлов, и, читая исходные файлы .NET, я обнаружил, что пара (и, возможно, больше) новых объектов создается при каждом вызове ReadSubtree, и кеширование повторно используемых объектов не производится (что я видел).

Возможно, считалось, что ReadSubtree () не использовался в массовом порядке, или, может быть, я просто беспокоясь, и мне просто нужно вызвать GC.Collect () после анализа файла ...

Надеюсь, что кто-то может пролить свет на это.

Заранее спасибо.

Обновление:

Спасибо за приятные и проницательные ответы.

Я глубже изучил исходный код .NET и обнаружил, что он более сложный, чем я мог себе представить. Я наконец отказался от идеи вызова этой функции в этом самом сценарии. Как отметил Стефан, xml-ридер никогда не передается посторонним, и я могу доверять коду, который анализирует xml-поток (который написан мной), поэтому я бы предпочел заставить каждый узел отвечать за объем данных, который они украсть из потока, чем использовать не очень тонкую в конце функцию ReadSubtree (), чтобы просто сохранить несколько строк кода.

Ответы [ 2 ]

10 голосов
/ 22 сентября 2008

ReadSubTree () дает вам XmlReader, который оборачивает оригинальный XmlReader. Этот новый читатель представляется потребителям как полный документ. Это может быть важно, если код, который вы передаете поддереву, думает, что он получает отдельный XML-документ. Например, свойство Depth нового Reader начинается с 0. Это довольно тонкая оболочка, поэтому вы не будете использовать больше ресурсов, чем если бы вы использовали исходный XmlReader напрямую. В приведенном вами примере это скорее всего, вы не очень-то получаете от читателя поддерева.

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

Как отметил Уилл, вы никогда не захотите вызывать GC.Collect (). Это никогда не улучшит производительность.

2 голосов
/ 22 сентября 2008

Предполагая, что все объекты создаются в обычной управляемой куче, а не в куче больших объектов (т. Е. Менее 85 КБ), здесь действительно не должно быть никаких проблем, это как раз то, с чем GC был разработан для работы.

Я бы предположил, что нет необходимости также вызывать GC.Collect в конце процесса, поскольку почти во всех случаях, когда GC сам планирует расписание коллекций, он может работать оптимальным образом (см. this сообщение в блоге для очень подробного объяснения GC, которое объясняет это намного лучше, чем я)

...