Запись 100'000 строк в XML-файл с Xdocument занимает слишком много времени

1

Я пытаюсь добавить узлы строк внутри xml файла, который уже существует, и добавить среднее значение (100 000 строк) внутри. Все работает, но это очень медленно. Не знаю почему. Я должен остановить свою программу, потому что прошло 10 минут и до сих пор не закончил ^^.

Я использую класс Xdocument для добавления узлов и XmlTextWriter, потому что мне нужно искать дочерний узел (регион) с атрибутом и после добавления узла внутри.

большое спасибо

Вот мой xmlFile

<World>
  <Matrix>
    <Regions>
      <Region id="0" min="x:0;y:0;z:0" max="x:256;y:16;z:256">
        <Structures type="cube" >
        </Structures>
      </Region>
      <Region id="1" min="x:256;y:0;z:0" max="x:512;y:16;z:256">
        <Structures type="cube" >
        </Structures>
      </Region>
      <Region id="2" min="x:512;y:0;z:0" max="x:768;y:16;z:256">
        <Structures type="cube" >
        </Structures>
      </Region>
      // till Region id="512" ...

И код, который я использую для вставки нового узла

Обновление: используйте StringBuilder для улучшения использования памяти. Как @threeFx советуют мне

// Loop 100'000 times in a recursive method ...

// Search the good node
var reg = arcadia.xDocumentWorld.Descendants("Region").FirstOrDefault(s => s.Attribute("id").Value == region.Index.ToString());
var struc = reg.Element("Structures");
//string posMin = "x:"+ node_.CubeNode.BoundingBox.Min.X+";y:"+ node_.CubeNode.BoundingBox.Min.Y+"z:"+ node_.CubeNode.BoundingBox.Min.Z;
//string posMax = "x:"+ node_.CubeNode.BoundingBox.Max.X+";y:"+ node_.CubeNode.BoundingBox.Max.Y+"z:"+ node_.CubeNode.BoundingBox.Max.Z;

var sbMin = new StringBuilder();
var sbMax = new StringBuilder();

sbMin.Append("x:");
sbMin.Append(node_.CubeNode.BoundingBox.Min.X);
sbMin.Append("y:");
sbMin.Append(node_.CubeNode.BoundingBox.Min.Y);
sbMin.Append("z:");
sbMin.Append(node_.CubeNode.BoundingBox.Min.Z);

sbMax.Append("x:");
sbMax.Append(node_.CubeNode.BoundingBox.Max.X);
sbMax.Append("y:");
sbMax.Append(node_.CubeNode.BoundingBox.Max.Y);
sbMax.Append("z:");
sbMax.Append(node_.CubeNode.BoundingBox.Max.Z);

var cube = new XElement("Cube", new XAttribute("id", node_.ItemGroup),
                                new XAttribute("min", sbMin.ToString()),
                                new XAttribute("max", sbMax.ToString()));

//Add the new cube node
struc.Add(cube);

//Dispose the StringBuilder
sbMin.Clear();
sbMax.Clear();

Как я вижу сейчас с тестовым анализом производительности,.Net Linq [List.FirstOrDefault] стоил большой производительности.

var reg = arcadia.xDocumentWorld.Descendants("Region").FirstOrDefault(s => s.Attribute("id").Value == region.Index.ToString());

Изображение 174551

  • 0
    Чтобы сузить круг вопросов: пытались ли вы профилировать (с меньшим набором данных) свою программу, чтобы увидеть, где находятся горячие точки?
  • 0
    Я только что закончил базовый тест производительности и поставил картинку. Я планирую сделать еще один тест с CLR Profiler для проверки памяти GC.
Теги:
linq-to-xml

1 ответ

3

Конкатенация строк с использованием + действительно неэффективна, потому что для каждого использования + создается новый экземпляр. Лучше, если вы используете StringBuilder для конкатенации строк:

StringBuilder sb = new StringBuilder();

sb.Append("x:");
sb.Append(node_.CubeNode.BoundingBox.Mix.X);
sb.Append("y:");
sb.Append(node_.CubeNode.BoundingBox.Min.Y);
sb.Append("z:");
sb.Append(node_.CubeNode.BoundingBox.Mix.Z);

string posMin = sb.ToString();

sb.Clear();

// do the same for posMax    
  • 0
    Спасибо за ваш ответ ^^ Вы правы. Я изменяю свой код сейчас и обновляю свое описание. Но результат все тот же, просто возможно улучшить использование памяти с помощью stringbuilder instand string. Построить мой XML-файл все еще очень медленно, когда я хочу его построить. У тебя есть идея почему?
  • 0
    @MehdiBugnard Должен ли метод быть рекурсивным? Рекурсивные методы в C # обычно медленнее (есть исключения), чем итерационные циклы, потому что C # не поддерживает оптимизацию вызовов Tail .
Показать ещё 5 комментариев

Ещё вопросы

Сообщество Overcoder
Наверх
Меню