Optimize UDDF export

Writing the samples/waypoints to UDDF export in a totally new way.
Previously the preparations for approximating waypoints was done for
every sample, now only for the events.

A few days ago it took 36 seconds for my test set of 8 dives to export
to UDDF.  This optimization round took it down from 0m4.745s to
0m0.253s.

Fixes #508

Signed-off-by: Miika Turkia <miika.turkia@gmail.com>
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
This commit is contained in:
Miika Turkia 2014-05-03 07:51:28 +03:00 committed by Dirk Hohndel
parent 3e17690525
commit 088017f67c

View file

@ -186,176 +186,191 @@
</informationbeforedive> </informationbeforedive>
<samples> <samples>
<xsl:for-each select="./divecomputer[1]/sample">
<!-- Position of previous waypoint --> <xsl:for-each select="divecomputer[1]/event | divecomputer[1]/sample">
<xsl:variable name="position"> <xsl:sort select="substring-before(@time, ':') * 60 + substring-before(substring-after(@time, ':'), ' ')" data-type="number" order="ascending"/>
<xsl:value-of select="position() - 1"/>
</xsl:variable>
<!-- Times of surrounding waypoints --> <xsl:variable name="events">
<xsl:variable name="timefirst"> <xsl:value-of select="count(preceding-sibling::event)"/>
<xsl:call-template name="time2sec"> </xsl:variable>
<xsl:with-param name="time">
<xsl:value-of select="../sample[position() = $position]/@time"/>
</xsl:with-param>
</xsl:call-template>
</xsl:variable>
<xsl:variable name="timesecond">
<xsl:call-template name="time2sec">
<xsl:with-param name="time">
<xsl:value-of select="./@time"/>
</xsl:with-param>
</xsl:call-template>
</xsl:variable>
<!-- Time difference between surrounding waypoints --> <xsl:choose>
<xsl:variable name="delta"> <xsl:when test="name() = 'event'">
<xsl:choose>
<xsl:when test="$timefirst &gt;= 0">
<xsl:value-of select="$timesecond - $timefirst"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="0"/>
</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<!-- Depths of surrounding waypoints --> <xsl:variable name="position">
<xsl:variable name="depthfirst"> <xsl:value-of select="position()"/>
<xsl:call-template name="depth2mm"> </xsl:variable>
<xsl:with-param name="depth">
<xsl:value-of select="../sample[position() = $position]/@depth"/>
</xsl:with-param>
</xsl:call-template>
</xsl:variable>
<xsl:variable name="depthsecond">
<xsl:call-template name="depth2mm">
<xsl:with-param name="depth">
<xsl:value-of select="./@depth"/>
</xsl:with-param>
</xsl:call-template>
</xsl:variable>
<!-- Approximated waypoints --> <!-- Times of surrounding waypoints -->
<xsl:variable name="timesec"> <xsl:variable name="timefirst">
<xsl:call-template name="time2sec"> <xsl:choose>
<xsl:with-param name="time"> <xsl:when test="../sample[position() = $position - 1 - $events]/@time != ''">
<xsl:value-of select="./@time"/>
</xsl:with-param>
</xsl:call-template>
</xsl:variable>
<!-- Crafting waypoints for events in-between samples -->
<xsl:for-each select="preceding-sibling::event[substring-before(@time, ':') * 60 + substring-before(substring-after(@time, ':'), ' ')&lt;$timesec and substring-before(@time, ':') * 60 + substring-before(substring-after(@time, ':'), ' ')&gt;($timesec - $delta)]">
<waypoint>
<depth>
<xsl:call-template name="approximatedepth">
<xsl:with-param name="timefirst">
<xsl:value-of select="$timefirst"/>
</xsl:with-param>
<xsl:with-param name="timesecond">
<xsl:value-of select="$timesecond"/>
</xsl:with-param>
<xsl:with-param name="depthfirst">
<xsl:value-of select="$depthfirst"/>
</xsl:with-param>
<xsl:with-param name="depthsecond">
<xsl:value-of select="$depthsecond"/>
</xsl:with-param>
<xsl:with-param name="timeevent">
<xsl:call-template name="time2sec"> <xsl:call-template name="time2sec">
<xsl:with-param name="time"> <xsl:with-param name="time">
<xsl:value-of select="@time"/> <xsl:value-of select="../sample[position() = $position - 1 - $events]/@time"/>
</xsl:with-param> </xsl:with-param>
</xsl:call-template> </xsl:call-template>
</xsl:with-param> </xsl:when>
</xsl:call-template> <xsl:otherwise>
</depth> <xsl:value-of select="0"/>
</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<xsl:variable name="timesecond">
<xsl:choose>
<xsl:when test="../sample[position() = $position - $events]/@time != ''">
<xsl:call-template name="time2sec">
<xsl:with-param name="time">
<xsl:value-of select="../sample[position() = $position - $events]/@time"/>
</xsl:with-param>
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="0"/>
</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<divetime> <!-- Depths of surrounding waypoints -->
<xsl:call-template name="time2sec"> <xsl:variable name="depthfirst">
<xsl:with-param name="time"> <xsl:choose>
<xsl:value-of select="@time"/> <xsl:when test="../sample[position() = $position - 1 - $events]/@depth != ''">
</xsl:with-param> <xsl:call-template name="depth2mm">
</xsl:call-template> <xsl:with-param name="depth">
</divetime> <xsl:value-of select="../sample[position() = $position - 1 - $events]/@depth"/>
</xsl:with-param>
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="0"/>
</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<xsl:variable name="depthsecond">
<xsl:choose>
<xsl:when test="../sample[position() = $position - $events]/@depth != ''">
<xsl:call-template name="depth2mm">
<xsl:with-param name="depth">
<xsl:value-of select="../sample[position() = $position - $events]/@depth"/>
</xsl:with-param>
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="0"/>
</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<xsl:if test="@name = 'gaschange'"> <xsl:variable name="time">
<switchmix> <xsl:value-of select="substring-before(@time, ':') * 60 + substring-before(substring-after(@time, ':'), ' ')"/>
<xsl:attribute name="ref"> </xsl:variable>
<xsl:value-of select="@value"/>
</xsl:attribute> <xsl:if test="$timesecond != $time">
</switchmix> <waypoint>
<depth>
<xsl:call-template name="approximatedepth">
<xsl:with-param name="timefirst">
<xsl:value-of select="$timefirst"/>
</xsl:with-param>
<xsl:with-param name="timesecond">
<xsl:value-of select="$timesecond"/>
</xsl:with-param>
<xsl:with-param name="depthfirst">
<xsl:value-of select="$depthfirst"/>
</xsl:with-param>
<xsl:with-param name="depthsecond">
<xsl:value-of select="$depthsecond"/>
</xsl:with-param>
<xsl:with-param name="timeevent">
<xsl:call-template name="time2sec">
<xsl:with-param name="time">
<xsl:value-of select="@time"/>
</xsl:with-param>
</xsl:call-template>
</xsl:with-param>
</xsl:call-template>
</depth>
<divetime><xsl:value-of select="$time"/></divetime>
<xsl:if test="@name = 'gaschange'">
<switchmix>
<xsl:attribute name="ref">
<xsl:value-of select="@value"/>
</xsl:attribute>
</switchmix>
</xsl:if>
<xsl:if test="@name = 'heading'">
<heading>
<xsl:value-of select="@value"/>
</heading>
</xsl:if>
<xsl:if test="not(@name = 'heading') and not(@name = 'gaschange')">
<alarm>
<xsl:value-of select="@name"/>
</alarm>
</xsl:if>
</waypoint>
</xsl:if> </xsl:if>
</xsl:when>
<xsl:otherwise>
<xsl:if test="@name = 'heading'"> <!-- Recorded waypoints and events occurring at the exact same time -->
<heading> <waypoint>
<xsl:value-of select="@value"/> <depth>
</heading> <xsl:value-of select="substring-before(./@depth, ' ')"/>
</xsl:if> </depth>
<xsl:if test="not(@name = 'heading') and not(@name = 'gaschange')"> <divetime>
<alarm> <xsl:call-template name="time2sec">
<xsl:value-of select="@name"/> <xsl:with-param name="time">
</alarm> <xsl:value-of select="./@time"/>
</xsl:if> </xsl:with-param>
</xsl:call-template>
</divetime>
</waypoint> <xsl:if test="./@pressure != ''">
</xsl:for-each> <tankpressure>
<!-- Approximated waypoints --> <xsl:value-of select="substring-before(./@pressure, ' ') * 100000"/>
</tankpressure>
</xsl:if>
<!-- Recorded waypoints and events occurring at the exact same time --> <xsl:if test="./@temp != ''">
<waypoint> <temperature>
<depth> <xsl:value-of select="format-number(substring-before(./@temp, ' ') + 273.15, '0.00')"/>
<xsl:value-of select="substring-before(./@depth, ' ')"/> </temperature>
</depth> </xsl:if>
<divetime> <xsl:variable name="time">
<xsl:call-template name="time2sec"> <xsl:value-of select="@time"/>
<xsl:with-param name="time"> </xsl:variable>
<xsl:value-of select="./@time"/>
</xsl:with-param>
</xsl:call-template>
</divetime>
<xsl:if test="./@pressure != ''"> <xsl:for-each select="preceding-sibling::event[@time = $time and @name='gaschange']/@value">
<tankpressure> <switchmix>
<xsl:value-of select="substring-before(./@pressure, ' ') * 100000"/> <xsl:attribute name="ref">
</tankpressure> <xsl:value-of select="."/>
</xsl:if> </xsl:attribute>
</switchmix>
</xsl:for-each>
<xsl:if test="./@temp != ''"> <xsl:for-each select="preceding-sibling::event[@time = $time and @name='heading']/@value">
<temperature> <heading>
<xsl:value-of select="format-number(substring-before(./@temp, ' ') + 273.15, '0.00')"/> <xsl:value-of select="."/>
</temperature> </heading>
</xsl:if> </xsl:for-each>
<xsl:variable name="time"> <xsl:for-each select="preceding-sibling::event[@time = $time and not(@name='heading' or @name='gaschange')]/@name">
<xsl:value-of select="@time"/> <alarm>
</xsl:variable> <xsl:value-of select="."/>
</alarm>
<xsl:for-each select="preceding-sibling::event[@time = $time and @name='gaschange']/@value"> </xsl:for-each>
<switchmix> <!-- Recorded waypoints -->
<xsl:attribute name="ref"> </waypoint>
<xsl:value-of select="."/> </xsl:otherwise>
</xsl:attribute> </xsl:choose>
</switchmix>
</xsl:for-each>
<xsl:for-each select="preceding-sibling::event[@time = $time and @name='heading']/@value">
<heading>
<xsl:value-of select="."/>
</heading>
</xsl:for-each>
<xsl:for-each select="preceding-sibling::event[@time = $time and not(@name='heading' or @name='gaschange')]/@name">
<alarm>
<xsl:value-of select="."/>
</alarm>
</xsl:for-each>
<!-- Recorded waypoints -->
</waypoint>
</xsl:for-each> </xsl:for-each>
</samples> </samples>