当我通过 XSL 将大量数据转换为 HTML 时,我经常遇到性能问题。这些数据通常只是几个大致这种形式的非常大的表:
<table>
<record>
<group>1</group>
<data>abc</abc>
</record>
<record>
<group>1</group>
<data>def</abc>
</record>
<record>
<group>2</group>
<data>ghi</abc>
</record>
</table>
在转换过程中,我想像这样对记录进行可视化分组
+--------------+
| Group 1 |
+--------------+
| abc |
| def |
+--------------+
| Group 2 |
+--------------+
| ghi |
+--------------+
这是一个愚蠢的实现(集合来自http://exslt.org。实际的实现有点不同,这只是一个例子):
<xsl:for-each select="set:distinct(/table/record/group)">
<xsl:variable name="group" select="."/>
<!-- This access needs to be made faster : -->
<xsl:for-each select="/table/record[group = $group]">
<!-- Do the table stuff -->
</xsl:for-each>
</xsl:for-each>
很容易看出这往往具有O(n^2)
复杂性。更糟糕的是,因为每条记录中都有很多字段。操作的数据可达几十MB,记录数可达5000条。最坏的情况下,每条记录都有自己的组和50个字段。更糟糕的是,还有另一个层次的分组可能,使得这O(n^3)
现在会有很多选择:
- 我可以找到一个涉及映射和嵌套数据结构的 Java 解决方案。但我想提高我的 XSLT 技能,所以这实际上是最后的选择。
- 我可能忘记了 Xerces/Xalan/Exslt 中的一个不错的功能,它可以更好地处理分组
- 我也许可以建立某种索引
/table/record/group
- 您可以向我证明,
<xsl:apply-templates/>
在这个用例中,该方法明显比该<xsl:for-each/>
方法快。
您认为如何O(n^2)
降低这种复杂性?