【问题标题】:XML structure for fastest lookup用于最快查找的 XML 结构
【发布时间】:2012-02-24 12:14:26
【问题描述】:

在下面的 xml 中查找某个“资源”时,以下结构中的一个或另一个更快吗?

示例 1。


<root>
 <resource key="res_test_1" value="test"/>
 <resource key="res_test_2" value="test 2"/>
 <resource key="res_test_3" value="test 3"/>
</root>

示例 2。


<root>
 <res_test_1>test</res_test_1>
 <res_test_2>test 2</res_test_2>
 <res_test_3>test 3</res_test_3>
</root>

“键”始终是有效的 XML 元素名称。

我问的是因为这组资源键/值将是 xml 文件的一部分,将由 XSL 处理,用同一 XML 文件的资源部分中的值替换 XML 中的某些“键” ...而且我想为所需的查找尽可能优化资源部分的结构。 我正在使用 C# 和 XslCompiledTransform 对象来运行转换。

我的直觉告诉我,当它们是实际的元素名称时,对象模型可能会更快地获取键,但我没有找到关于此类问题的建议。也许考虑这个问题并不重要,因为整个 xml 文档在转换过程中都会在内存中。

编辑(从这里往下添加更多信息): 正如我已经指出的那样,这个问题可能是理论上的(专注于几毫秒是不相关的),但输入这个问题的原因是为了获得对我所问的确切内容的意见 - 一种方式比另一种方式更快(在列出的两个示例中),当涉及到在 XML 结构中定位数据时。无论出于何种原因,一种或另一种是首选方式。

在我看来,第一个示例需要为处理器提供更多“工作”,以便在请求时定位和返回值。

这是示例 1 的示例 XPath: /root/resource[@key="res_test_2"]/@value

示例 2 的对应 XPath: /root/res_test_2

此外,示例 2 的结构需要更少的空间,这将缩短加载时间,如下面的答案之一所示。一个很好的观点,至少对于非常大的文档而言。

当我想到它时:示例 2 的一个明显缺点是 XSD 模式没有多大用处,因为这部分 XML 将具有动态元素名称.. 这可能是建议将所有值放在属性中(下面的答案)是关于。

我制作了这些 XPath 示例,因为它们易于演示。在我之前写的 XSL 转换中将需要类似的查找,但这个问题的重点应该是文档的结构,作为一个更通用的问题。

谢谢, 安德烈亚斯

【问题讨论】:

  • 查找速度更多地取决于用于查找的算法——两种提供的数据结构之间的差异很小,并且使用相同的算法不会导致显着的性能差异。请编辑问题并描述完整的问题:源 XML 文档、想要的结果和转换规则。那么我很高兴向您展示一个有效的转换。

标签: xml xslt data-structures


【解决方案1】:

不久前,我询问了有关 XSLT 性能的问题,得到了以下答案:

使用属性而不是元素可以提高性能。执行 XPath 匹配时,属性更快,因为它们是松散类型的。这使得模式的验证更容易。

(见this question)

【讨论】:

  • 感谢您的链接!那里有很多非常好的点。但是,一个松散类型的值......处理起来会不会更慢(与类型值相反)?或者,作者的意思是不是要查找基于元素的实际“文本”的值,而这些值是元素 text 的实际“文本”的一部分?
【解决方案2】:

在 sample1 和 sample2 之间,唯一的区别是 .. 您正在将元素转换为属性 .. 读取子属性将花费与读取子元素相同的精力 ..

示例:

<!--example1-->
<root>
  <child id="something"/>
</root>

<!--example2-->
<root>
  <child>
    <id>somthing</id>
  </child>
</root>

从第一个示例中读取“somthing”的 Xpath 是 /root/child/@id/. 和 Xpath 用于读取 /root/child/id/. ..

这没什么大的区别..但是如果你看一下大小..example2有点大..现在假设你有一个huge这样的节点列表..那么example2文件会比 example1 大。
所以 example2 的数据权重很高

回到您的示例 .. 如果您查看结构 .. sample1 看起来比 sample2 更长 ..
假设相同的文件具有大量具有相应层次结构的数据 ..
如果您尝试使用 C# 代码读取 sample1 和 sample2 .. 代码加载 sample1 需要更多时间(由于其大小).. 与处理速度(我的意思是读取节点的过程)相比,可以忽略不计。

@OP,如你所知..

XPath for Sample 1: /root/resource[@key="res_test_2"]/@value

Corresponding XPath for Sample 2: /root/res_test_2

与 Sample2 相比,Sample1 肯定下降了 1 级 .. 但正如我之前提到的 .. 我观察到这不会对解析器产生太大影响,我已经解释了大小对 的影响阅读文件 .. 我想告诉你一些事情。
使用属性应该是明智的选择,这不是一个规则,但我们通常使用属性作为元数据..
示例:

<root>
  <child id="1">some Data</child>
  <child id="2">Some other Data</child>
</root>

如果您查看上面的示例 XML,属性即“ID”用作有关子节点数据的元数据,ID 不是数据,它只是一个子消息。


再举一个例子:

<html>
   <body>
       <div class="style1">Here is the display text.</div>
   </body>
</html>

上面的例子只是一个 HTML 代码 :) 属性 Class 的值是“style1” .. 然后在 CSS 文件中使用这个类名来为 标签下的文本添加属性和样式>

【讨论】:

  • 嗨!并感谢您的关注!为了澄清起见,我还为我的 XML 添加了两个 XPath 示例(请参阅上面的原始问题),并且还添加了根元素。我发现你的样品与我的略有不同。在我的第二个示例中,我得到离根更近一层的“密钥”,这可能更容易和更快地查找。我相信你是对的,处理速度可以忽略不计,但是,我发现这是一个有趣的问题。您对大小和加载时间的看法很好!
  • @AndreasJansson,现在解释得更清楚了,请参考提供的更多示例。希望它可以帮助您理解这个概念:)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-02-02
  • 1970-01-01
  • 1970-01-01
  • 2021-09-29
  • 2011-04-07
  • 1970-01-01
相关资源
最近更新 更多