I'm creating a client-side pie chart in XSLT 1.0, without extensions or external dependencies (i.e., cannot use FXSLT, EXSLT, JavaScript, etc.).The code is slow; at least fifteen iterations are necessary to get the correct precision required for the angles used by the pie chart. (I'm looking for help that doesn't involve loop unrolling, if possible.)How would you speed calculating the sine function?<xsl:template name=power>  <xsl:param name=n/>  <xsl:param name=exponent/>  <xsl:param name=result select=1 />  <xsl:choose>    <xsl:when test=$exponent = 0>1</xsl:when>    <xsl:when test=$exponent = 1>      <xsl:value-of select=$result * $n/>    </xsl:when>    <xsl:otherwise>      <xsl:call-template name=power>        <xsl:with-param name=n select=$n/>        <xsl:with-param name=exponent select=$exponent - 1/>        <xsl:with-param name=result select=$result * $n/>      </xsl:call-template>                              </xsl:otherwise>  </xsl:choose></xsl:template><xsl:template name=factorial>  <xsl:param name=n select=1 />  <xsl:choose>    <xsl:when test=$n &lt;= 1>1</xsl:when>    <xsl:otherwise>      <xsl:variable name=f>        <xsl:call-template name=factorial>           <xsl:with-param name=n select=$n - 1 />        </xsl:call-template>      </xsl:variable>      <xsl:value-of select=$n * $f />    </xsl:otherwise>  </xsl:choose></xsl:template><!-- sin(x) = x - x^3/3! + x^5/5! - x^7/7! ... --><xsl:template name=sin>  <xsl:param name=degrees />  <xsl:param name=radians select=$degrees * $PI div 180 />  <xsl:param name=iter select=1 />  <xsl:param name=maxiter select=15 />  <xsl:param name=result select=0 />  <xsl:variable name=taylor select=($iter - 1) * 2 + 1 />  <xsl:variable name=numerator>    <xsl:call-template name=power>      <xsl:with-param name=n select=$radians />      <xsl:with-param name=exponent select=$taylor />    </xsl:call-template>  </xsl:variable>  <xsl:variable name=denominator>    <xsl:call-template name=factorial>      <xsl:with-param name=n select=$taylor />    </xsl:call-template>  </xsl:variable>  <xsl:variable name=term>    <xsl:choose>      <xsl:when test=$iter mod 2 = 1>        <xsl:value-of select=$numerator div $denominator />      </xsl:when>      <xsl:otherwise><xsl:value-of select=-1 * $numerator div $denominator /></xsl:otherwise>    </xsl:choose>  </xsl:variable>  <xsl:choose>    <xsl:when test=$iter &lt; $maxiter>      <xsl:call-template name=sin>        <xsl:with-param name=radians select=$radians />        <xsl:with-param name=iter select=$iter + 1 />        <xsl:with-param name=result select=$result + $term />      </xsl:call-template>    </xsl:when>    <xsl:otherwise><xsl:value-of select=$result /></xsl:otherwise>  </xsl:choose></xsl:template>A similar question exists for C, but loop unrolling is awkward in XSLT due to its immutable variables.
Calculation of trigonometric sine function
performance;recursion;mathematics;xslt
Do not use power and factorial. Notice that$$x - \frac{x^3}{3!} + \frac{x^5}{5!} - \frac{x^7}{7!} + \ldots = x(1 - \frac{x^2}{2*3}(1 - \frac{x^2}{4*5}(1 - \frac{x^2}{6*7}(1 - \ldots))) \ldots) $$Now calculate it backwards from the innermost term:  <!-- sin(x) = x(1 - (x^2/2*3)(1 - (x^2/4*5)(1 - (x^2/6*7)))) -->  <xsl:template name=sin>    <xsl:param name=degrees />    <xsl:param name=radians select=$degrees * $PI div 180 />    <xsl:param name=iter select=31 />    <xsl:param name=result select=1 />    <xsl:variable name=term select=($radians * $radians) div (($iter - 1) * $iter) />    <xsl:choose>      <xsl:when test=$iter &gt; 2>        <xsl:call-template name=sin>          <xsl:with-param name=radians select=$radians />          <xsl:with-param name=iter select=$iter - 2 />          <xsl:with-param name=result select=1 - ($term * $result) />        </xsl:call-template>      </xsl:when>      <xsl:otherwise><xsl:value-of select=$radians * $result /></xsl:otherwise>    </xsl:choose>  </xsl:template>