XDocument.Load похоже всегда загружает весь файл в память и парсит его.
А надо-то всего-навсего стащить один элемент из файла (который еще находится как назло в конце) и закрыть его.
Как оптимизировать такой код для больших файлов?
XDocument xdoc = XDocument.Load(path);
DateTime date = (DateTime)(xdoc.Root.Element(XName.Get("date", "http://myns.com")));
Подозреваю, что придется использовать XmlReader с его мудреным api. Помогите плз.
Re: LINQ to xml и производительность на больших файлах.
Здравствуйте, wisdom, Вы писали:
W>XDocument.Load похоже всегда загружает весь файл в память и парсит его. W>А надо-то всего-навсего стащить один элемент из файла (который еще находится как назло в конце) и закрыть его.
W>Как оптимизировать такой код для больших файлов? W>
Здравствуйте, wisdom, Вы писали:
W>XDocument.Load похоже всегда загружает весь файл в память и парсит его. W>А надо-то всего-навсего стащить один элемент из файла (который еще находится как назло в конце) и закрыть его.
Для такого случая лучше всего написать специализированный код, который вообще не будет просматривать файл с головы.
То есть алгоритм примерно такой:
1. Задаемся характерным размером этого элемента (Size)
2. Читаем последние Size байт файла, конвертим в строку (тут возможна тонкость с кодировками, но для UTF-8, UTF-16, и однобайтных кодировок она легко разрешима)
3. Смотрим, попал ли нужный тег в буфер
4. Если нет, то читаем еще Size байт назад, конвертим в строку, склеиваем (использовать StringBuilder!), переходим к 3
5. Как только тег целиком поместился в буфере, вытаскиваем его содержимое.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re: LINQ to xml и производительность на больших файлах.
W>Подозреваю, что придется использовать XmlReader с его мудреным api. Помогите плз.
У него очень простой API. Проще некуда. Советую проверять свойство Depth. Будет что-нибудь вроде:
bool found = false;
int depth = reader.Depth;
while (reader.Read()) {
if (reader.Depth == depth + 1) {
if (reader.IsStartElement ("date", ...)) {
found = true;
}
}
}