Done (previous patch cleaned).
This patch optimizes XSL transformations contained in docbook-xsl (1.78.1).
Tested with 9.5.2
time make html
real 1m21.989s
user 1m21.392s
sys 0m0.484s
1) time make xslthtml
(before the patch)
real 29m19.904s
user 29m18.804s
sys 0m0.888s
2) time make xslthtml
(after the patch)
real 3m8.483s
user 3m7.556s
sys 0m0.864s
To make sure that the result of the transformation is the same:
After 1):
mv html html.xslt1
After 2):
mv html html.xslt2
for f in *.xslt*/*.html; do sed -e
's/id=\"\(ftn\.\)\?id[a-z][0-9]\+\"/id=\"id\"/g' -i $f ; sed -e
's/href=\"[^#]*#\(ftn\.\)\?id[a-z][0-9]\+\"/href=\"#\"/g' -i $f; done
diff -u -r html.xslt1 html.xslt2
Best regards,
Alexander
04.05.2016 03:44, Peter Eisentraut пишет:
On 5/3/16 4:13 PM, Oleg Bartunov wrote:
As it stated in
http://www.postgresql.org/message-id/562e061b.1090...@postgrespro.ru
the xml performance may be greatly improved. Alexander, what is current
state of art of your patch ? How slow is xml in compare to sgml ?
Please make sure the patch is registered in the next commit fest.
diff --git a/doc/src/sgml/stylesheet-xhtml-speedup.xsl b/doc/src/sgml/stylesheet-xhtml-speedup.xsl
new file mode 100644
index 0000000..d52b48e
--- /dev/null
+++ b/doc/src/sgml/stylesheet-xhtml-speedup.xsl
@@ -0,0 +1,327 @@
+<?xml version="1.0" encoding="utf-8"?>
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+ version="1.0"
+ xmlns="http://www.w3.org/1999/xhtml"
+ exclude-result-prefixes="#default">
+
+<!-- common/labels.xsl -->
+<xsl:template match="appendix" mode="label.markup">
+ <xsl:choose>
+ <xsl:when test="@label">
+ <xsl:value-of select="@label"/>
+ </xsl:when>
+ <xsl:when test="string($appendix.autolabel) != 0">
+ <xsl:if test="$component.label.includes.part.label != 0 and
+ ancestor::part">
+ <xsl:variable name="part.label">
+ <xsl:apply-templates select="ancestor::part"
+ mode="label.markup"/>
+ </xsl:variable>
+ <xsl:if test="$part.label != ''">
+ <xsl:value-of select="$part.label"/>
+ <xsl:apply-templates select="ancestor::part"
+ mode="intralabel.punctuation"/>
+ </xsl:if>
+ </xsl:if>
+ <xsl:variable name="format">
+ <xsl:call-template name="autolabel.format">
+ <xsl:with-param name="format" select="$appendix.autolabel"/>
+ </xsl:call-template>
+ </xsl:variable>
+ <xsl:choose>
+ <xsl:when test="$label.from.part != 0 and ancestor::part">
+ <xsl:number from="part" count="appendix" format="{$format}" level="any"/>
+ </xsl:when>
+ <xsl:otherwise>
+<!-- speed optimizations for pgsql-docs -->
+ <xsl:number value="count(../preceding-sibling::part/appendix) + count(preceding-sibling::appendix) + 1" format="{$format}" />
+<!-- <xsl:number from="book|article"
+ count="appendix" format="{$format}" level="any"/> -->
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:when>
+ </xsl:choose>
+</xsl:template>
+
+<!-- common/labels.xsl -->
+<xsl:template match="chapter" mode="label.markup">
+ <xsl:choose>
+ <xsl:when test="@label">
+ <xsl:value-of select="@label"/>
+ </xsl:when>
+ <xsl:when test="string($chapter.autolabel) != 0">
+ <xsl:if test="$component.label.includes.part.label != 0 and
+ ancestor::part">
+ <xsl:variable name="part.label">
+ <xsl:apply-templates select="ancestor::part"
+ mode="label.markup"/>
+ </xsl:variable>
+ <xsl:if test="$part.label != ''">
+ <xsl:value-of select="$part.label"/>
+ <xsl:apply-templates select="ancestor::part"
+ mode="intralabel.punctuation"/>
+ </xsl:if>
+ </xsl:if>
+ <xsl:variable name="format">
+ <xsl:call-template name="autolabel.format">
+ <xsl:with-param name="format" select="$chapter.autolabel"/>
+ </xsl:call-template>
+ </xsl:variable>
+ <xsl:choose>
+ <xsl:when test="$label.from.part != 0 and ancestor::part">
+ <xsl:number from="part" count="chapter" format="{$format}" level="any"/>
+ </xsl:when>
+ <xsl:otherwise>
+<!-- speed optimizations for pgsql-docs -->
+ <xsl:number value="count(../preceding-sibling::part/chapter) + count(preceding-sibling::chapter) + 1" format="{$format}" />
+<!-- <xsl:number from="book" count="chapter" format="{$format}" level="any"/> -->
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:when>
+ </xsl:choose>
+</xsl:template>
+
+<!-- xhtml/autoidx.xsl -->
+<xsl:template match="indexterm" mode="reference">
+ <xsl:param name="scope" select="."/>
+ <xsl:param name="role" select="''"/>
+ <xsl:param name="type" select="''"/>
+ <xsl:param name="position"/>
+ <xsl:param name="separator" select="''"/>
+
+ <xsl:variable name="term.separator">
+ <xsl:call-template name="index.separator">
+ <xsl:with-param name="key" select="'index.term.separator'"/>
+ </xsl:call-template>
+ </xsl:variable>
+
+ <xsl:variable name="number.separator">
+ <xsl:call-template name="index.separator">
+ <xsl:with-param name="key" select="'index.number.separator'"/>
+ </xsl:call-template>
+ </xsl:variable>
+
+ <xsl:variable name="range.separator">
+ <xsl:call-template name="index.separator">
+ <xsl:with-param name="key" select="'index.range.separator'"/>
+ </xsl:call-template>
+ </xsl:variable>
+
+ <xsl:choose>
+ <xsl:when test="$separator != ''">
+ <xsl:value-of select="$separator"/>
+ </xsl:when>
+ <xsl:when test="$position = 1">
+ <xsl:value-of select="$term.separator"/>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:value-of select="$number.separator"/>
+ </xsl:otherwise>
+ </xsl:choose>
+
+ <xsl:choose>
+ <xsl:when test="@zone and string(@zone)">
+ <xsl:call-template name="reference">
+ <xsl:with-param name="zones" select="normalize-space(@zone)"/>
+ <xsl:with-param name="position" select="position()"/>
+ <xsl:with-param name="scope" select="$scope"/>
+ <xsl:with-param name="role" select="$role"/>
+ <xsl:with-param name="type" select="$type"/>
+ </xsl:call-template>
+ </xsl:when>
+ <xsl:otherwise>
+ <a>
+ <xsl:apply-templates select="." mode="class.attribute"/>
+ <xsl:variable name="title">
+ <xsl:choose>
+ <xsl:when test="$index.prefer.titleabbrev != 0">
+ <xsl:apply-templates select="(ancestor-or-self::set|ancestor-or-self::book|ancestor-or-self::part|ancestor-or-self::reference|ancestor-or-self::partintro|ancestor-or-self::chapter|ancestor-or-self::appendix|ancestor-or-self::preface|ancestor-or-self::article|ancestor-or-self::section|ancestor-or-self::sect1|ancestor-or-self::sect2|ancestor-or-self::sect3|ancestor-or-self::sect4|ancestor-or-self::sect5|ancestor-or-self::refentry|ancestor-or-self::refsect1|ancestor-or-self::refsect2|ancestor-or-self::refsect3|ancestor-or-self::simplesect|ancestor-or-self::bibliography|ancestor-or-self::glossary|ancestor-or-self::index|ancestor-or-self::webpage|ancestor-or-self::topic)[last()]" mode="titleabbrev.markup"/>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:apply-templates select="(ancestor-or-self::set|ancestor-or-self::book|ancestor-or-self::part|ancestor-or-self::reference|ancestor-or-self::partintro|ancestor-or-self::chapter|ancestor-or-self::appendix|ancestor-or-self::preface|ancestor-or-self::article|ancestor-or-self::section|ancestor-or-self::sect1|ancestor-or-self::sect2|ancestor-or-self::sect3|ancestor-or-self::sect4|ancestor-or-self::sect5|ancestor-or-self::refentry|ancestor-or-self::refsect1|ancestor-or-self::refsect2|ancestor-or-self::refsect3|ancestor-or-self::simplesect|ancestor-or-self::bibliography|ancestor-or-self::glossary|ancestor-or-self::index|ancestor-or-self::webpage|ancestor-or-self::topic)[last()]" mode="title.markup"/>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:variable>
+
+ <xsl:attribute name="href">
+ <xsl:choose>
+ <xsl:when test="$index.links.to.section = 1">
+ <xsl:call-template name="href.target">
+ <xsl:with-param name="object" select="(ancestor-or-self::set|ancestor-or-self::book|ancestor-or-self::part|ancestor-or-self::reference|ancestor-or-self::partintro|ancestor-or-self::chapter|ancestor-or-self::appendix|ancestor-or-self::preface|ancestor-or-self::article|ancestor-or-self::section|ancestor-or-self::sect1|ancestor-or-self::sect2|ancestor-or-self::sect3|ancestor-or-self::sect4|ancestor-or-self::sect5|ancestor-or-self::refentry|ancestor-or-self::refsect1|ancestor-or-self::refsect2|ancestor-or-self::refsect3|ancestor-or-self::simplesect|ancestor-or-self::bibliography|ancestor-or-self::glossary|ancestor-or-self::index|ancestor-or-self::webpage|ancestor-or-self::topic)[last()]"/>
+<!-- speed optimizations for pgsql-docs -->
+ <xsl:with-param name="context" select="(/book/index[count(ancestor::node()|$scope) = count(ancestor::node()) and ($role = @role or $type = @type or (string-length($role) = 0 and string-length($type) = 0))])[1]"/>
+ </xsl:call-template>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:call-template name="href.target">
+ <xsl:with-param name="object" select="."/>
+ <xsl:with-param name="context" select="(//index[count(ancestor::node()|$scope) = count(ancestor::node()) and ($role = @role or $type = @type or (string-length($role) = 0 and string-length($type) = 0))] | //setindex[count(ancestor::node()|$scope) = count(ancestor::node()) and ($role = @role or $type = @type or (string-length($role) = 0 and string-length($type) = 0))])[1]"/>
+ </xsl:call-template>
+ </xsl:otherwise>
+ </xsl:choose>
+
+ </xsl:attribute>
+
+ <xsl:value-of select="$title"/> <!-- text only -->
+ </a>
+
+ <xsl:variable name="id" select="(@id|@xml:id)[1]"/>
+ <xsl:if test="key('endofrange', $id)[count(ancestor::node()|$scope) = count(ancestor::node()) and ($role = @role or $type = @type or (string-length($role) = 0 and string-length($type) = 0))]">
+ <xsl:apply-templates select="key('endofrange', $id)[count(ancestor::node()|$scope) = count(ancestor::node()) and ($role = @role or $type = @type or (string-length($role) = 0 and string-length($type) = 0))][last()]" mode="reference">
+ <xsl:with-param name="position" select="position()"/>
+ <xsl:with-param name="scope" select="$scope"/>
+ <xsl:with-param name="role" select="$role"/>
+ <xsl:with-param name="type" select="$type"/>
+ <xsl:with-param name="separator" select="$range.separator"/>
+ </xsl:apply-templates>
+ </xsl:if>
+ </xsl:otherwise>
+ </xsl:choose>
+</xsl:template>
+
+<!-- xhtml/chunk-common.xsl -->
+<xsl:template name="chunk-all-sections">
+ <xsl:param name="content">
+ <xsl:apply-imports/>
+ </xsl:param>
+
+<!-- speed optimizations for pgsql-docs -->
+ <xsl:variable name="prev-v1" select="preceding::*[(self::sect1 and $chunk.section.depth > 0) or (self::sect2 and $chunk.section.depth > 1) or (self::sect3 and $chunk.section.depth > 2) or (self::sect4 and $chunk.section.depth > 3) or (self::sect5 and $chunk.section.depth > 4)][1]"/>
+
+ <xsl:variable name="prev-v2" select="(ancestor::sect1[$chunk.section.depth > 0 and not(ancestor::*/processing-instruction('dbhtml')[normalize-space(.) ='stop-chunking'])][1] |ancestor::sect2[$chunk.section.depth > 1 and not(ancestor::*/processing-instruction('dbhtml')[normalize-space(.) ='stop-chunking'])][1] |ancestor::sect3[$chunk.section.depth > 2 and not(ancestor::*/processing-instruction('dbhtml')[normalize-space(.) ='stop-chunking'])][1] |ancestor::sect4[$chunk.section.depth > 3 and not(ancestor::*/processing-instruction('dbhtml')[normalize-space(.) ='stop-chunking'])][1] |ancestor::sect5[$chunk.section.depth > 4 and not(ancestor::*/processing-instruction('dbhtml')[normalize-space(.) ='stop-chunking'])][1] |ancestor::section[$chunk.section.depth > count(ancestor::section) and not(ancestor::*/processing-instruction('dbhtml')[normalize-space(.) ='stop-chunking'])][1])[last()]"/>
+
+ <xsl:variable name="prev" select="(preceding::book[1] |preceding::preface[1] |preceding::chapter[1] |preceding::appendix[1] |preceding::part[1] |preceding::reference[1] |preceding::refentry[1] |preceding::colophon[1] |preceding::article[1] |preceding::topic[1] |preceding::bibliography[parent::article or parent::book or parent::part][1] |preceding::glossary[parent::article or parent::book or parent::part][1] |preceding::index[$generate.index != 0] [parent::article or parent::book or parent::part][1] |preceding::setindex[$generate.index != 0][1] |ancestor::set |ancestor::book[1] |ancestor::preface[1] |ancestor::chapter[1] |ancestor::appendix[1] |ancestor::part[1] |ancestor::reference[1] |ancestor::article[1] |ancestor::topic[1] |$prev-v1 |$prev-v2)[last()]"/>
+
+<!-- speed optimizations for pgsql-docs -->
+ <xsl:variable name="next-v1" select="following::*[self::sect1 or self::sect2 or self::sect3 or self::sect4 or self::sect5][1]"/>
+
+ <xsl:variable name="next-v2" select="(descendant::sect1[$chunk.section.depth > 0 and not(ancestor::*/processing-instruction('dbhtml')[normalize-space(.) ='stop-chunking'])][1] |descendant::sect2[$chunk.section.depth > 1 and not(ancestor::*/processing-instruction('dbhtml')[normalize-space(.) ='stop-chunking'])][1] |descendant::sect3[$chunk.section.depth > 2 and not(ancestor::*/processing-instruction('dbhtml')[normalize-space(.) ='stop-chunking'])][1] |descendant::sect4[$chunk.section.depth > 3 and not(ancestor::*/processing-instruction('dbhtml')[normalize-space(.) ='stop-chunking'])][1] |descendant::sect5[$chunk.section.depth > 4 and not(ancestor::*/processing-instruction('dbhtml')[normalize-space(.) ='stop-chunking'])][1] |descendant::section[$chunk.section.depth > count(ancestor::section) and not(ancestor::*/processing-instruction('dbhtml')[normalize-space(.) ='stop-chunking'])][1])[1]"/>
+
+ <xsl:variable name="next" select="(following::book[1] |following::preface[1] |following::chapter[1] |following::appendix[1] |following::part[1] |following::reference[1] |following::refentry[1] |following::colophon[1] |following::bibliography[parent::article or parent::book or parent::part][1] |following::glossary[parent::article or parent::book or parent::part][1] |following::index[$generate.index != 0] [parent::article or parent::book][1] |following::article[1] |following::topic[1] |following::setindex[$generate.index != 0][1] |descendant::book[1] |descendant::preface[1] |descendant::chapter[1] |descendant::appendix[1] |descendant::article[1] |descendant::topic[1] |descendant::bibliography[parent::article or parent::book][1] |descendant::glossary[parent::article or parent::book or parent::part][1] |descendant::index[$generate.index != 0] [parent::article or parent::book][1] |descendant::colophon[1] |descendant::setindex[$generate.index != 0][1] |descendant::part[1] |descendant::reference[1] |descendant::refentry[1] |$next-v1 |$next-v2)[1]"/>
+
+
+ <xsl:call-template name="process-chunk">
+ <xsl:with-param name="prev" select="$prev"/>
+ <xsl:with-param name="next" select="$next"/>
+ <xsl:with-param name="content" select="$content"/>
+ </xsl:call-template>
+
+</xsl:template>
+
+
+<xsl:template name="make.legalnotice.head.links">
+ <!-- * the following ID is used as part of the legalnotice filename; -->
+ <!-- * we need it in order to construct the filename for use in the -->
+ <!-- * value of the href attribute on the link -->
+
+ <xsl:param name="ln-node" select="(//legalnotice)[1]"/>
+
+ <xsl:param name="linktype">
+ <xsl:choose>
+ <xsl:when test="contains($html.head.legalnotice.link.types, ' ')">
+ <xsl:value-of select="normalize-space( substring-before($html.head.legalnotice.link.types, ' '))"/>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:value-of select="$html.head.legalnotice.link.types"/>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:param>
+ <xsl:param name="remaining.linktypes" select="concat( normalize-space( substring-after($html.head.legalnotice.link.types, ' ')),' ')"/>
+ <xsl:if test="not($linktype = '')">
+ <!-- Compute name of legalnotice file (see titlepage.xsl) -->
+ <xsl:variable name="file">
+ <xsl:call-template name="ln.or.rh.filename">
+ <xsl:with-param name="node" select="$ln-node"/>
+ </xsl:call-template>
+ </xsl:variable>
+
+ <link rel="{$linktype}">
+ <xsl:attribute name="href">
+ <xsl:value-of select="$file"/>
+ </xsl:attribute>
+ <xsl:attribute name="title">
+<!-- speed optimizations for pgsql-docs -->
+ <xsl:apply-templates select="/book/bookinfo/legalnotice" mode="object.title.markup.textonly"/>
+ </xsl:attribute>
+ </link>
+<!-- speed optimizations for pgsql-docs -->
+<!-- <xsl:call-template name="make.legalnotice.head.links">
+ < ! - - * pop the next value off the list of link types - - >
+ <xsl:with-param name="linktype" select="substring-before($remaining.linktypes, ' ')"/>
+ < ! - - * remove the link type from the list of remaining link types - - >
+ <xsl:with-param name="remaining.linktypes" select="substring-after($remaining.linktypes, ' ')"/>
+ </xsl:call-template> -->
+ </xsl:if>
+</xsl:template>
+
+<!-- xhtml/html.xsl (needed for the following "reference" template) -->
+<xsl:template name="id.attribute">
+ <xsl:param name="node" select="."/>
+ <xsl:param name="conditional" select="1"/>
+ <xsl:choose>
+ <xsl:when test="$generate.id.attributes = 0">
+ <!-- No id attributes when this param is zero -->
+ </xsl:when>
+ <xsl:when test="$conditional = 0 or $node/@id or $node/@xml:id">
+ <xsl:attribute name="id">
+ <xsl:call-template name="object.id">
+ <xsl:with-param name="object" select="$node"/>
+ </xsl:call-template>
+ </xsl:attribute>
+ </xsl:when>
+ </xsl:choose>
+</xsl:template>
+
+<!-- xhtml/autoidx.xsl -->
+<xsl:template name="reference">
+ <xsl:param name="scope" select="."/>
+ <xsl:param name="role" select="''"/>
+ <xsl:param name="type" select="''"/>
+ <xsl:param name="zones"/>
+
+ <xsl:choose>
+ <xsl:when test="contains($zones, ' ')">
+ <xsl:variable name="zone" select="substring-before($zones, ' ')"/>
+ <xsl:variable name="target" select="key('sections', $zone)"/>
+
+ <a>
+ <xsl:apply-templates select="." mode="class.attribute"/>
+ <xsl:call-template name="id.attribute"/>
+ <xsl:attribute name="href">
+ <xsl:call-template name="href.target">
+ <xsl:with-param name="object" select="$target[1]"/>
+ <xsl:with-param name="context" select="//index[count(ancestor::node()|$scope) = count(ancestor::node()) and ($role = @role or $type = @type or (string-length($role) = 0 and string-length($type) = 0))][1]"/>
+ </xsl:call-template>
+ </xsl:attribute>
+ <xsl:apply-templates select="$target[1]" mode="index-title-content"/>
+ </a>
+ <xsl:text>, </xsl:text>
+ <xsl:call-template name="reference">
+ <xsl:with-param name="zones" select="substring-after($zones, ' ')"/>
+ <xsl:with-param name="position" select="position()"/>
+ <xsl:with-param name="scope" select="$scope"/>
+ <xsl:with-param name="role" select="$role"/>
+ <xsl:with-param name="type" select="$type"/>
+ </xsl:call-template>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:variable name="zone" select="$zones"/>
+ <xsl:variable name="target" select="key('sections', $zone)"/>
+
+ <a>
+ <xsl:apply-templates select="." mode="class.attribute"/>
+ <xsl:call-template name="id.attribute"/>
+ <xsl:attribute name="href">
+ <xsl:call-template name="href.target">
+ <xsl:with-param name="object" select="$target[1]"/>
+<!-- speed optimizations for pgsql-docs -->
+ <xsl:with-param name="context" select="/book/index[count(ancestor::node()|$scope) = count(ancestor::node()) and ($role = @role or $type = @type or (string-length($role) = 0 and string-length($type) = 0))][1]"/>
+ </xsl:call-template>
+ </xsl:attribute>
+ <xsl:apply-templates select="$target[1]" mode="index-title-content"/>
+ </a>
+ </xsl:otherwise>
+ </xsl:choose>
+</xsl:template>
+
+</xsl:stylesheet>
diff --git a/doc/src/sgml/stylesheet.xsl b/doc/src/sgml/stylesheet.xsl
index 7967b36..8b01f41 100644
--- a/doc/src/sgml/stylesheet.xsl
+++ b/doc/src/sgml/stylesheet.xsl
@@ -6,6 +6,7 @@
<xsl:import href="http://docbook.sourceforge.net/release/xsl/current/xhtml/chunk.xsl"/>
<xsl:include href="stylesheet-common.xsl" />
+<xsl:include href="stylesheet-xhtml-speedup.xsl" />
<!-- Parameters -->
--
Sent via pgsql-docs mailing list (pgsql-docs@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-docs