Subject: Re: [xsl] How to output the start execution time and the end execution time? From: "Abel Braaksma (Exselt) abel@xxxxxxxxxx" <xsl-list-service@xxxxxxxxxxxxxxxxxxxxxx> Date: Sat, 6 Sep 2014 17:26:24 -0000 |
Actually, thinking about it, there is a problem with this approach and Dimitre's approach. XSLT does not define the order of execution. In fact, the sibling statements in the main code can take place in any order, or even in parallel. To know the time that is taken to process your XSLT, your best bet is to use internal counters that your processor provides that remove the JIT, static analysis, XPath parsing and other preprocessing times from your processing. Provided you want an XSLT solution, we must force the XSLT to apply an order of processing by introducing dependencies. The cleanest way I can think of is to use a new XSLT 3.0 concept for accumulators: pre-descent and post-descent evaluation (i.e. before visiting a node and after visiting a node, after means: after all children are processed). The problem with accumulators: it is a new XSLT 3.0 feature and currently no processor fully supports them. However, it will work something like the following (taking reported and resolved public bugs into account for the syntax, search bugzilla for accumulators if you are interested). To prevent optimizations (where functions can be pre-evaluated), let's take Dimitre's approach and force evaluation on the right moment by making it dependent on the visited node. <!-- use streaming to force order of evaluation --> <xsl:mode streamable="yes" /> <xsl:variable static="yes" name="timedocurl" select=" 'http://developer.yahooapis.com/TimeService/V1/getTime?appid=YahooDemo&fo rmat=ms&x=' " /> <!-- id-param is there to prevent caching --> <xsl:function name="my:time"> <xsl:param name="id" as="xs:string" /> <xsl:value-of select=" doc($timedocurl || $id)/*/*:Timestamp/node()" /> </xsl:function> <xsl:accumulator name="time" streamable="yes" Initial-value="()"> <xsl:accumulator-rule match="/" phase="start" select="my:time(generate-id(.))" /> <xsl:accumulator-rule match="/" phase="end" select="my:time(generate-id(.) || '-end')" /> </xsl:accumulator> <!-- do the normal processing (if necessary, change your templates to be properly streamable --> <xsl:template match="/"> <!-- this calls the pahase="start" accumulator rule --> <xsl:value-of select="'Start-time: ' || accumulator-before('time')" /> <!-- regular processing --> <xsl:apply-templates /> <!-- this calls the phase="end" accumulator rules --> <xsl:value-of select="'End-time: ' || accumulator-after('time')"/> <xsl:template> This approach works guaranteed cross-processor because the order of execution is defined here: the processor *must* call the accumulator-after only after all the processing is done (as a by-product, this means that accumulator-after can only be called in post-descent instructions, meaning, *after* all children are processed, which in this case is the following sibling of xsl:appy-templates). This example can be extended to show the processing time of each visited node, irrespective of optimizations. It is probably a good idea to use a local time server / URI resolver though, so that time lag caused by networking is not troubling the timings. There are alternative ways of forcing the order of execution, but I thought I'd use the opportunity to introduce accumulators. We currently support a subset of them and are working on full support once the WG has cleared all bugs on them. Cheers, Abel Braaksma Exselt streaming XSLT 3.0 processor http://exselt.net > -----Original Message----- > From: Abel Braaksma (Exselt) abel@xxxxxxxxxx [mailto:xsl-list- > service@xxxxxxxxxxxxxxxxxxxxxx] > Sent: Saturday, September 06, 2014 6:31 PM > To: xsl-list@xxxxxxxxxxxxxxxxxxxxxx > Subject: Re: [xsl] How to output the start execution time and the end > execution time? > > Hi Roger, > > Functions and constructs in XSLT and XPath are stable (barring a few > exceptions). Calling a function with the same argument twice will yield the > same result for both calls. The functions current-time(), current-dateTime() > and current-date() will therefor always return the same time (with a slight > caveat for static and dynamic evaluation phases, but let's not digress). > > The only way out here is extension functions, or a trick with XSLT 3.0 using > streaming, because the xsl:stream instruction is deemed non-stable (i.e., it > will re-invoke the url at the href argument each time it is called). Whether an > extension function helps depends whether your processor allows non-stable > extension functions, but I believe most, if not all, processors do. > > Here's a (workable) trick that works with all XSLT 3.0 processors, however > you might want to choose a local resource instead that returns the current > date-time, for performance reasons. > > > <xsl:mode streamable="yes" name="time" on-no-match="shallow-skip" > > > <!-- may need an actual argument to force re-evaluation --> <xsl:function > name="my:current-time"> > <xsl:stream href="http://time.is"> > <xsl:apply-templates mode="time" /> > </xsl:stream> > </xsl:function> > > <!-- match the element that contains the time --> <xsl:template > match="div[@id = 'twd']"> > <xsl:value-of select="." /> > </xsl:template> > > <xsl:template match="/"> > <xsl:value-of select="my:current-time()" /> > ... do the processing ... > <xsl:value-of select="my:current-time()" /> </xsl:template> > > > Note: the page http://time.is currently does not deliver proper XML (and on > my search for a time server that did deliver proper XML or even proper > XHTML I did not find any). If you can convince your processor not to cache > the result of unparsed-text, you can use the following with the same server > as a workaround (ugly, but it shows the principle): > > <xsl:value-of select="replace(unparsed-text('http://time.is/'), > '.+twd">([^<]+).*', '$1', 'sm')" /> > > Cheers, > Abel > > > > -----Original Message----- > > From: Costello, Roger L. costello@xxxxxxxxx [mailto:xsl-list- > > service@xxxxxxxxxxxxxxxxxxxxxx] > > Sent: Saturday, September 06, 2014 11:47 AM > > To: xsl-list@xxxxxxxxxxxxxxxxxxxxxx > > Subject: [xsl] How to output the start execution time and the end > > execution time? > > > > Hi Folks, > > > > I would like to: > > > > 1. Output the time that my XSLT program starts processing 2. Do the > > processing 3. Output the time that my XSLT program finishes processing > > > > This doesn't work: > > > > <xsl:template match="/"> > > <xsl:value-of select="current-time()" /> > > ... do the processing ... > > <xsl:value-of select="current-time()" /> > > </xsl:template> > > > > What is the correct way to accomplish this? > > > > /Roger
Current Thread |
---|
|
<- Previous | Index | Next -> |
---|---|---|
Re: [xsl] How to output the start e, Dimitre Novatchev dn | Thread | Re: [xsl] How to output the start e, Michael Kay mike@xxx |
Re: [xsl] How to output the start e, Wolfgang Laun wolfga | Date | Re: [xsl] How to output the start e, Abel Braaksma (Exsel |
Month |