Модераторы: Poseidon, Snowy, bems, MetalFan
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Посоветуйте xml парсер 
V
    Опции темы
Dom
Дата 19.11.2008, 09:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 121
Регистрация: 7.8.2005

Репутация: 1
Всего: 4



Столкнулся с такой проблемой.
Данные сохраняются в xml-файл. Использую стандартный TXMLDocument. Проблема всего одна. Нереально много потребляет оперативки. Скажем если на выходе получаем файл размером 50Мб, то уходит 1Гб оперативки. почему так не понимаю, то ли сам парсер такой (судя по описанию очень на это похоже), то ли структура файла "виновата". Структура файла очень разветвеленная. Примерно можно описать так - несколько сотен деревьев, с числом узлов до тысячи, в узлах текстовая информация.
Одним словом, сохранить файл не всегда удается. Иногда память заканчивается раньше и выдается Оut of memory.
Xml-файл используется только для хранения данных - запись и чтение.

В связи с этим вопрос, может кто-то посоветовать какой-то альтернативный парсер, который будет более щадяще обращаться с памятью? Скорость в этом случае не так важна, чтение и запись процессы однократные, можно и потерпеть чуток. К тому же судя по статьям (хоть и не самым свежим) быстродействие MS парсера далеко от идеала.

Пока остановил свой взгляд на TjanXMLParser2 и TNativeXml, судя по описанию нечто более достойное, чем стандартный компонент. Может кто-то сможет посоветовать что-то более конкретное, подходящее именно под описанную задачу? Не охота как-то переписывать массу кода и тестировать все парсеры. smile

ЗЫ. Или может есть какие-то спецприемы при работе со стандартным парсером, что уменьшит потребление им оперативки?
PM MAIL   Вверх
Poseidon
Дата 19.11.2008, 10:46 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Delphi developer
****


Профиль
Группа: Комодератор
Сообщений: 5273
Регистрация: 4.2.2005
Где: Гомель, Беларусь

Репутация: 53
Всего: 133



Цитата(Dom @  19.11.2008,  09:03 Найти цитируемый пост)
Скажем если на выходе получаем файл размером 50Мб, то уходит 1Гб оперативки. почему так не понимаю, то ли сам парсер такой (судя по описанию очень на это похоже), то ли структура файла "виновата".
Скорее всего у тебя где-то утечка. На таких количествах данных она приумножается во много раз, вот и вытикает гиг. Пересмотри код, особенно там где циклы.



--------------------
Если хочешь, что бы что-то работало - используй написанное, 
если хочешь что-то понять - пиши сам...
PM MAIL ICQ   Вверх
aktuba
Дата 19.11.2008, 13:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Смышленный
***


Профиль
Группа: Завсегдатай
Сообщений: 1915
Регистрация: 24.4.2006
Где: Планета Земля

Репутация: 16
Всего: 38



Цитата(Poseidon @  19.11.2008,  11:46 Найти цитируемый пост)
Скорее всего у тебя где-то утечка. На таких количествах данных она приумножается во много раз, вот и вытикает гиг. Пересмотри код, особенно там где циклы.

100%


--------------------
user posted image
PM MAIL WWW Skype   Вверх
Dom
Дата 20.11.2008, 01:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 121
Регистрация: 7.8.2005

Репутация: 1
Всего: 4



Погляжу еще разок.
PM MAIL   Вверх
Dom
Дата 20.11.2008, 11:40 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 121
Регистрация: 7.8.2005

Репутация: 1
Всего: 4



Поигрался с xml, сделал отдельно маленький тестовый пример - погонять структуру файла.
Каждый узел в этом примере имеет двух потомков.
Вот как происходит заполнение.
В итоге имеем на выходе файл размером 4,5М и 80М оперативки под XMLDocument.
1. Собственно в чем тут я не прав? Где та самая утечка происходит, понять не могу. Подскажите пожалуйста.
2. Как правильно освобождать память от XMLDocument? Как уничтожить этот объект после того как все сохранено в файл? FreeAndNil(XML) не помогает.

Код

unit uMain;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, XMLIntf, XMLDoc;

type
  TForm1 = class(TForm)
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);

  procedure WriteNode(XMLNode: IXMLNode; Count: integer);
  var
  Node: IXMLNode;
  begin
    if Count > 0 then
    begin
      Node := XMLNode.AddChild('Left');
      Node.Attributes['Name'] := 'BlaBlaBla';
      Node.Attributes['S'] := 'Ha';
      Node.Attributes['Value'] := 25;
      WriteNode(Node, Count-1);
      Node := XMLNode.AddChild('Right');
      Node.Attributes['Name'] := 'BlaBlaBla';
      Node.Attributes['S'] := 'Ha';
      Node.Attributes['Value'] := 25;
      WriteNode(Node, Count-1);
    end;
  end;

var
XML: IXMLDocument;
i: integer;
Node: IXMLNode;
begin
  XML := TXMLDocument.Create(Application);
  XML.Active := true;
  XML.DocumentElement := XML.CreateElement('Root','');
  for i := 1 to 50 do   // число элементов Tree в файле
  begin
    Node := XML.DocumentElement.AddChild('Tree');
    WriteNode(Node, 10);   // глубина каждого Tree (число уровней)
  end;
  XML.SaveToFile('E:\temp\1.xml');
  // как уничтожить объект XML ?
end;

end.


PM MAIL   Вверх
Dom
Дата 20.11.2008, 22:10 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 121
Регистрация: 7.8.2005

Репутация: 1
Всего: 4



Видимо никто не сталкивался с такой траблой.
Значит буду менять парсер. Если не забуду отпишусь. smile
PM MAIL   Вверх
Poseidon
Дата 21.11.2008, 10:31 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Delphi developer
****


Профиль
Группа: Комодератор
Сообщений: 5273
Регистрация: 4.2.2005
Где: Гомель, Беларусь

Репутация: 53
Всего: 133



Код
var
XML: TXMLDocument;
i: integer;
Node: IXMLNode;
begin
  XML := TXMLDocument.Create(Application);
  XML.Active := true;
  XML.DocumentElement := XML.CreateElement('Root','');
  for i := 1 to 50 do   // число элементов Tree в файле
  begin
    Node := XML.DocumentElement.AddChild('Tree');
    WriteNode(Node, 10);   // глубина каждого Tree (число уровней)
  end;
  XML.SaveToFile('E:\temp\1.xml');
  // как уничтожить объект XML ?
  XML.Active:= False;
  XML.Free;
end;



--------------------
Если хочешь, что бы что-то работало - используй написанное, 
если хочешь что-то понять - пиши сам...
PM MAIL ICQ   Вверх
Dom
Дата 21.11.2008, 13:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 121
Регистрация: 7.8.2005

Репутация: 1
Всего: 4



Poseidon, спасибо! С освобождением памяти вроде как прояснилось.
Но работа с оперативкой все равно остается самым узким местом.

Заменил в тестовом примере, который привел чуть выше, TXMLDocument на TNativeXml.
Объем занимаемой оперативки уменьшился ровно в 3 раза на тестовом примере, до 25Мб, вместо 75Мб.

Заодно из любопытства померял скорость. Разброс значений у TXMLDocument оказался гораздо больше от 5322 до 3878, среднее значение 4368. Для TNativeXml разброс был от 2359 до 2453, среднее 2394.

Ниже сам код (требуется установить NativeXml и кинуть пару кнопок на форму), может кому-то пригодится.

Код

unit uMain;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, XMLIntf, XMLDoc, NativeXML;

type
  TForm1 = class(TForm)
    Button1: TButton;
    Button2: TButton;
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);

  procedure WriteNode(XMLNode: IXMLNode; Count: integer);
  var
  Node: IXMLNode;
  begin
    if Count > 0 then
    begin
      Node := XMLNode.AddChild('Left');
      Node.Attributes['Name'] := 'BlaBlaBla';
      Node.Attributes['S'] := 'NOT';
      Node.Attributes['Value'] := 25;
      WriteNode(Node, Count-1);
      Node := XMLNode.AddChild('Right');
      Node.Attributes['Name'] := 'BlaBlaBla';
      Node.Attributes['S'] := 'AND';
      Node.Attributes['Value'] := 25;
      WriteNode(Node, Count-1);
    end;
  end;

var
XML: TXMLDocument;
i, t: integer;
Node: IXMLNode;
begin
  t := GetTickCount;

  XML := TXMLDocument.Create(Application);
  XML.Active := true;
  XML.DocumentElement := XML.CreateElement('Root','');
  for i := 1 to 50 do
  begin
    Node := XML.DocumentElement.AddChild('Tree');
    WriteNode(Node, 10);
  end;
  XML.SaveToFile('E:\temp\1.xml');
  XML.Active:= False;
  XML.Free;

  ShowMessage(IntToStr(GetTickCount - t));
end;

procedure TForm1.Button2Click(Sender: TObject);

  procedure WriteNode(XMLNode: TXmlNode; Count: integer);
  var
  Node: TXmlNode;
  begin
    if Count > 0 then
    begin
      Node := XMLNode.NodeNew('Left');
      Node.WriteAttributeString('Name', 'BlaBlaBla');
      Node.WriteAttributeString('S', 'NOT');
      Node.WriteAttributeInteger('Value', 25);
      WriteNode(Node, Count-1);
      Node := XMLNode.NodeNew('Right');
      Node.WriteAttributeString('Name', 'BlaBlaBla');
      Node.WriteAttributeString('S', 'NOT');
      Node.WriteAttributeInteger('Value', 25);
      WriteNode(Node, Count-1);
    end;
  end;

var
XML: TNativeXml;
i, t: integer;
Node: TXmlNode;
begin
  t := GetTickCount;

  XML := TNativeXml.CreateName('Root');
  for i := 1 to 50 do
  begin
    Node := XML.Root.NodeNew('Tree');
    WriteNode(Node, 10);
  end;
  XML.SaveToFile('E:\temp\1.xml');
  XML.Free;

  ShowMessage(IntToStr(GetTickCount - t));
end;

end.

Как этот компонент поведет себя в реальных задачах покажет время.
PM MAIL   Вверх
Akella
Дата 22.11.2008, 15:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Творец
****


Профиль
Группа: Модератор
Сообщений: 18485
Регистрация: 14.5.2003
Где: Корусант

Репутация: 36
Всего: 329



http://www.delphilab.ru/content/view/56/73/

Цитата

Данная библиотека представляет собой XML parser.
По сравнению с TXMLDocument, быстрее в разы.

PM MAIL   Вверх
Dom
Дата 22.11.2008, 20:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 121
Регистрация: 7.8.2005

Репутация: 1
Всего: 4



Цитата(Akella @  22.11.2008,  15:12 Найти цитируемый пост)
http://www.delphilab.ru/content/view/56/73/


Цитата

Данная библиотека представляет собой XML parser.
По сравнению с TXMLDocument, быстрее в разы.

Спасибо. Скорость не так критична как объем занимаемой оперативки. Рекомендуешь попробовать?
Эту страничку находил раньше и скачал на всякий случай исходники (по-моему это кто-то из местных приложил руку к доработке, читал где-то на форуме, когда искал ответ на свой вопрос). Собственно выбор стоял между NativeXml и janXMLParser2. Выбор пока пал на первый, очень уж подкупил хороший хелп к компоненту.
За вчера уже успел половину кода перевести на NativeXml. Объем потребляемой памяти уменьшился почти в 4 раза посравнению с TXMLDocument. Скорость визуально тоже возросла. Но хочется еще чего-то получше. smile
Попробую на тестовом примере погонять и второй парсер.
PM MAIL   Вверх
Dom
Дата 22.11.2008, 21:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 121
Регистрация: 7.8.2005

Репутация: 1
Всего: 4



Погонял janXMLParser2 в тесте. Скорость почти в два раза выше, чем у NativeXml (в среднем 1370, по сравнению с 2394). Но и одновременно памяти откушивает в два раза больше (50Мб). При этом сперва уходит ~35Мб на создание структуры xml-документа, а остальное затрачивается при сохранении его на диск.

Сравнение конечно призводилось на очень простом примере, все возможности парсеров не задействовались, но кое-какая информация получена. Остановлю свой выбор на NativeXml. Другого пока нет.
Всем спасибо. smile
PM MAIL   Вверх
Akella
Дата 23.11.2008, 13:18 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Творец
****


Профиль
Группа: Модератор
Сообщений: 18485
Регистрация: 14.5.2003
Где: Корусант

Репутация: 36
Всего: 329



Цитата(Dom @  22.11.2008,  20:44 Найти цитируемый пост)
Рекомендуешь попробовать?

рекомендую лишь потому что выложено на ДельфиЛаб. Но сам не использовал.
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Delphi: Общие вопросы"
SnowyMetalFan
bemsPoseidon
Rrader

Запрещается!

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

  • Литературу по Дельфи обсуждаем здесь
  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь
  • 90% ответов на свои вопросы можно найти в DRKB (Delphi Russian Knowledge Base) - крупнейшем в рунете сборнике материалов по Дельфи


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Snowy, MetalFan, bems, Poseidon, Rrader.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Delphi: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0552 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.