Kevin,
The problem with your chunked template is that it isn't really bisection. You
don't get true O(log n) performance - you only get O(n / x) performance, x
being dependent upon your chunk size. Your template would need to be recursive
to get the real benefit of bisection. Here it is:
<xsl:template name="HexToDec">
<xsl:param name="HexData" />
<xsl:param name="Hex" select="'0123456789ABCDEF'" />
<xsl:choose>
<xsl:when test="contains($HexData, ',')">
<xsl:variable name="midpoint" select="floor(string-length($HexData) div
2) - 1" />
<xsl:variable name="half1" select="substring($HexData, 1, $midpoint)" />
<xsl:variable name="half2" select="substring($HexData, $midpoint + 1)" />
<xsl:call-template name="HexToDec">
<xsl:with-param name="HexData" select="concat($half1,
substring-before($half2, ','))" />
<xsl:with-param name="Hex" select="$Hex" />
</xsl:call-template>
<xsl:text>,</xsl:text>
<xsl:call-template name="HexToDec">
<xsl:with-param name="HexData" select="substring-after($half2, ',')" />
<xsl:with-param name="Hex" select="$Hex" />
</xsl:call-template>
</xsl:when>
<xsl:when test="starts-with($HexData, '0x')">
<xsl:value-of select="string-length(substring-before($Hex,
substring($HexData, 3, 1))) * 16 + string-length(substring-before($Hex,
substring($HexData, 4, 1)))" />
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$HexData" />
</xsl:otherwise>
</xsl:choose>
</xsl:template>
Try it out, please - I'm actually very curious to see how the performance and
memory usage stand up against the other templates in the various processors.
You should be able to use it with any processor now, too.
~ Scott
-----Original Message-----
From: Bulgrien, Kevin [mailto:Kevin(_dot_)Bulgrien(_at_)GDSATCOM(_dot_)com]
Sent: Wednesday, March 21, 2012 5:19 PM
To: 'xsl-list(_at_)lists(_dot_)mulberrytech(_dot_)com'
Subject: RE: [xsl] String conversion problem when string is large
And this variant seems to balance speed and memory usage, but still kills all
the engines I have except the Saxonica engine.
Execution time: 1.039s (1039ms)
Memory used: 30306880
<xsl:call-template name="HexToDec">
<xsl:with-param name="HexData" select="." />
<xsl:with-param name="Hex" select="'0123456789ABCDEF'" /> </xsl:call-template>
<xsl:template name="HexToDec">
<xsl:param name="HexData" />
<xsl:param name="Hex" />
<xsl:if test="string-length($HexData) > 0">
<xsl:text>,</xsl:text>
<xsl:value-of
select="string-length(
substring-before(
$Hex, substring($HexData, 3, 1))) * 16 +
string-length(
substring-before(
$Hex, substring($HexData, 4, 1)))" />
<xsl:call-template name="HexToDec">
<xsl:with-param name="HexData"
select="substring-after($HexData, ',')" />
<xsl:with-param name="Hex" select="$Hex" />
</xsl:call-template>
</xsl:if>
</xsl:template>
To let other XSLT engines that do not optimize recursion, a divide and conquer
approach was simple enough to concoct. The chunk size was a bit arbitrary, but
is about half of what it took to break another engine at its default stack
depth. xsltproc took about 2.8 seconds. sablotron took 5.8 seconds. I won't
bother to show times for the Windows engines as the platform difference makes
them hard to compare fairly.
Execution time: 832ms
Memory used: 26545336
<xsl:call-template name="HexToDecChunker">
<xsl:with-param name="HexData" select="." />
<xsl:with-param name="Hex" select="'0123456789ABCDEF'" /> </xsl:call-template>
<xsl:template name="HexToDecChunker">
<xsl:param name="HexData" />
<xsl:param name="Hex" />
<xsl:variable name="ChunkLen" select="5120" />
<xsl:variable name="InputLen" select="string-length($HexData)" />
<xsl:choose>
<xsl:when test="$InputLen > $ChunkLen">
<xsl:call-template name="HexToDec">
<xsl:with-param name="HexData"
select="substring($HexData, 1, $ChunkLen)" />
<xsl:with-param name="Hex" select="$Hex" />
</xsl:call-template>
<xsl:call-template name="HexToDecChunker">
<xsl:with-param name="HexData"
select="substring($HexData, $ChunkLen + 1)" />
<xsl:with-param name="Hex" select="$Hex" />
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<xsl:call-template name="HexToDec">
<xsl:with-param name="HexData" select="$HexData" />
<xsl:with-param name="Hex" select="$Hex" />
</xsl:call-template>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
What an adventure. There are probably a lot more ways to tackle this issue.
Kevin Bulgrien
This message and/or attachments may include information subject to GD Corporate
Policy 07-105 and is intended to be accessed only by authorized personnel of
General Dynamics and approved service providers. Use, storage and transmission
are governed by General Dynamics and its policies. Contractual restrictions
apply to third parties. Recipients should refer to the policies or contract to
determine proper handling. Unauthorized review, use, disclosure or
distribution is prohibited. If you are not an intended recipient, please
contact the sender and destroy all copies of the original message.
--~------------------------------------------------------------------
XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list
To unsubscribe, go to: http://lists.mulberrytech.com/xsl-list/
or e-mail: <mailto:xsl-list-unsubscribe(_at_)lists(_dot_)mulberrytech(_dot_)com>
--~--
--~------------------------------------------------------------------
XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list
To unsubscribe, go to: http://lists.mulberrytech.com/xsl-list/
or e-mail: <mailto:xsl-list-unsubscribe(_at_)lists(_dot_)mulberrytech(_dot_)com>
--~--