- xml - AJAX/Jquery XML 解析
- 具有多重继承的 XML 模式
- .net - 枚举序列化 Json 与 XML
- XML 简单类型、简单内容、复杂类型、复杂内容
在工作中,我们使用 XML 日志文件。每条日志消息都是 <message>
用 <date>
block 和 <time>
子节点,有<submessage>
block ,<table>
构造等,日志文件可以使用一些 Delphi 处理和稍后的 XSLT 转换为本地化的 HTML。
对于中等大小的日志文件(大约 2 MB),我们遇到了性能问题(加载 XML 和执行一些基本操作需要一分钟时间),我可以将它们缩减为这样的测试项目(编辑:更新代码并添加测量):
procedure TForm1.PrepareTest(MessageCount : integer);
var
XML : IXMLDocument;
i : integer;
begin
XML := NewXMLDocument;
XML.DocumentElement := XML.CreateNode('root');
for i := 1 to MessageCount do
begin
XML.DocumentElement.AddChild('message').Text := 'Test Text';
end;
XML.SaveToFile(XML_NAME);
end;
procedure TForm1.XMLTest;
var
StartTime : Cardinal;
XML : IXMLDocument;
begin
StartTime := GetTickCount();
XML := NewXMLDocument;
XML.LoadFromFile(XML_NAME);
Memo1.Lines.Add('Node count: ' + IntToStr(XML.DocumentElement.ChildNodes.Count));
Memo1.Lines.Add('Time: ' + FloatToStr((GetTickCount() - StartTime) / 1000) + ' seconds');
end;
这导致以下时间测量(节点数每列增加 25%,所有时间均以毫秒为单位):
Node count 8000 10000 12500 15625 19531 24413 30516 38145 47681
Base test time 484 781 1140 1875 2890 4421 6734 10672 16812
Variation 1 32 47 62 78 78 141
Variation 2 2656 3157 3906 5015 6532 8922 12140 17391 24985
(delta Base) 2172 2376 2766 3140 3642 4501 5406 6719 8173
注意两个变体,第一个是 LoadFromFile
只有第二个是在 XML 的开头(!)另外添加 10000 个节点,如 PrepareTest
确实如此,这是最坏的情况,但是查看基础测试的增量,即使这样也没有显示出二次效应。另请注意,计算节点可以用任何其他操作代替,因此看起来涉及的 XML 文件的一些延迟初始化/验证导致了问题,并且之后的任何操作都显示了预期的行为。
内存使用率不高,最后一个测试用例(47681 个节点)的内存使用峰值为 39 MB,其 XML 文件大小为 1.3 MB。
加载 XML 后要做的第一件事(例如读取或写入一些节点或访问节点计数)很慢并且它显示二次运行时行为,因此任何超过 10 MB 的日志文件都无法使用.
我们已经通过解析 100 条消息的小块来解决性能问题以及其他一些问题,而且我知道 Delphi XML 例程不适合/过度杀伤这个用例 - 使用不同的 XML 库很可能停止性能问题。所以我不是在寻求问题的解决方案(尽管如果知道问题是否可以在不使用不同的 XML 库的情况下得到解决会很有趣)。
我的问题是:Delphi XML 例程和 MSXML 的二次运行时行为的原因是什么?我无法想象在 XML 加载/解析/验证中会导致这种情况的事情,除了真正“愚蠢”的事情,比如管理链接列表而不是树中的节点,但我可能会忽略一些东西,也许与 DOM 相关。
最佳答案
我同意 mj2008 的观点,即 XML 不适合记录日志。也就是说,这个问题和一般的大型 XML 文件可以通过使用 SAX 得到更快的处理。 ,它在解析传入的 XML 数据流时抛出事件,这使您可以在从磁盘读取项目时对其进行处理,从而有效地减轻了在将其交给 XSLT 之前将其全部加载到内存中的指数级增长。
我很遗憾我还没有在 Delphi 中完成 SAX,但我怀疑最难的部分是实现所需的 SAX 接口(interface)(例如 ISAXContentHandler ),但 Delphi 有 TInterfacedObject 和 TAutoObject 以及其他一些专门用于此的部分。
关于xml - Delphi XML (MSXML) 例程的二次运行时,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14365910/
我最近购买了《C 编程语言》并尝试了 Ex 1-8这是代码 #include #include #include /* * */ int main() { int nl,nt,nb;
早上好!我有一个变量“var”,可能为 0。我检查该变量是否为空,如果不是,我将该变量保存在 php session 中,然后调用另一个页面。在这个新页面中,我检查我创建的 session 是否为空,
我正在努力完成 Learn Python the Hard Way ex.25,但我无法理解某些事情。这是脚本: def break_words(stuff): """this functio
我是一名优秀的程序员,十分优秀!