Manual

5 — Analysing

The debugger answers the question "what does my stylesheet do, instruction by instruction?". This chapter covers three others, asked once the transformation is correct:

  • where the time goes — which template really costs, and why;
  • which templates are used — and which are never triggered;
  • where this output line comes from — which XSLT instruction and which source node produced it.

The first two rely on the profiler, the third on back-mapping.


5.1 Profiling a transformation

Click Run with Saxon Profiler (⏱) on the toolbar. The button is active only in the IDLE state — a profiling run does not start during a debugging session.

The profiler reuses exactly the F5 configuration: the designated stylesheet (or that of the active tab), the XML document, the XSLT parameters and the entry point. You therefore measure what you run.

The console traces the run:

--- Starting Saxon Profiler ---
XML  : C:\...\input.xml
XSLT : C:\...\main.xsl
--- Profiling completed in 412 ms ---
[profiler] 4 templates profiled, 6 total calls.
[templates] 4 declared, 2 never triggered on this run.

At the end of the run, the Profiler tab comes to the front automatically. The Templates tab is filled at the same time, by the same run.

Two differences from F5

  • Profiling ignores your breakpoints. It never stops: stopping would distort the measurement. Leave your breakpoints in place, they are not in the way.
  • Profiling writes no file: neither the main output, nor the files of an xsl:result-document. Profiling a stylesheet has no side effect on your disk. To get the output, run the transformation with F5.

The profiler's diagnostics appear in the console, not in the status message: [ERROR] Profiler: configure an XSLT file via ⚙ or open a .xsl in the editor., [ERROR] Profiler: no XML file found in workspace., or [ERROR] Profiler: XSLT file not found — ….


5.2 Reading the hot spots

The upper part of the Profiler tab shows Hotspots (by self time): a table with one row per template or function executed, sorted by default from the most to the least costly, the hottest rows being the most coloured.

ColumnWhat it gives
Template / Functionthe name of the named template, of the function, or the pattern of a match template
Locationthe file and line of its declaration
Callsthe number of invocations on this run
Total (ms)inclusive time — this template and everything it calls
Self (ms)self time — this template alone, callees excluded
Avg (µs)average duration of one call

The Total / Self distinction is the key to reading it. A root template almost always shows the largest Total — it encompasses the whole transformation, which teaches nothing. The default sort is therefore on self time: that is what names the real culprit.

A header sums up the run: 4 templates · 6 calls · 412.0 ms.

Double-click a row to open its declaration in the editor, highlighted in blue. The Enter key on the selected row does the same. Click a column header to change the sort — by number of calls, for example.


5.3 The call tree

Below the hot spots, Call tree shows the same measurements in their call context: the root at 100 %, then each template called with its share of the total time.

This is what tells apart two situations that the hot-spot table conflates:

  • a template slow in itself, called once;
  • a template fast but called five thousand times, whose cumulative cost dominates the run.

The second is spotted by its Calls column and by its place in the tree — under the xsl:for-each that triggers it.

Double-click a node to jump to the matching declaration.


5.4 Coverage: the Templates tab

The Templates tab answers another question: is everything I wrote actually used?

It lists every template and function declared by the stylesheet, xsl:include / xsl:import modules included — and not only those that ran.

ColumnContents
Status✔ green Triggered on this run / ⚠ orange Never triggered on this run
Template / Functionthe name or the match pattern
Modethe mode of the template, if it has one
Locationfile and line of the declaration
Callsnumber of invocations on this run
Self (ms)its self time

A header sums up: 4 declared · 2 untriggered · 6 calls.

The Untriggered only check box leaves only the ⚠ rows — the direct working list. Double-click a row to open its declaration.

What "never triggered" means — and does not mean

Coverage is relative to the document you profiled. A template not triggered on input.xml may be indispensable to other.xml.

The method that gives a real verdict: profile several representative documents in turn. What is triggered by none of them is a serious candidate.

Each run replaces the previous one: the counters do not accumulate from one profiling to the next.

Before any profiling, the two tabs show their prompt — Run the profiler (⏱) to analyze performance. and Run the profiler (⏱) to analyze template coverage.


5.5 Jumping from the output back to its source

You are looking at a line of the result and wondering who wrote it. Back-mapping answers in one gesture.

After a transformation to HTML, XML or Text, in the output tab:

Ctrl + click a line of the result.

Two purple highlights appear at once:

  • in the stylesheet, the line of the XSLT instruction that produced this output;
  • in the source document, the line of the XML node that served as context at that moment.

The correspondence is established iteration by iteration: in a loop over five books, Ctrl+click on the third book's line designates the same instruction, but the third <book>. The xsl:include / xsl:import modules are traversed — the instruction designated may sit in another file, which is opened as needed.

The console confirms the capture at the end of each run:

[Back-mapping] 36 segment(s) captured — Ctrl+click in the output to jump back to the source

The secondary outputs produced by xsl:result-document are mapped like the main output: open one from the explorer, and Ctrl+click works there.

The source node highlighted is the context node of the instruction, not necessarily the one whose value is displayed. In an xsl:for-each select="book", it is the <book> element of the current iteration that is designated, not its <title> child.


5.6 The other direction: "Show generated output"

The symmetrical question — does this instruction really produce something, and what? — is asked from the stylesheet.

  1. Right-click a line of an .xsl tab.
  2. Show generated output.

The output tab comes to the front and every range produced by that line is highlighted there — five ranges if the instruction ran five times.

If the line produced nothing — an xsl:message, an instruction never reached — the console says so unambiguously:

[Back-mapping] No known generated output for this line

It is a quick way to confirm that an xsl:if branch really is dead.


5.7 Switching back-mapping on or off

The Output back-mapping setting in the Settings menu switches it on or off. It is on by default.

The mapping is captured during the transformation, not after. Switching the setting back on therefore adds nothing to an output already produced, and the console says so:

[Back-mapping] Enabled — run the transformation again to capture the mapping

Run it again, and Ctrl+click works once more.

The output tab is closed and regenerated at every run, back-mapping on or off: what you read always matches the latest run.


5.8 Limits worth knowing

  • Back-mapping is not available on PDF export. It covers HTML, XML and Text outputs, main and secondary alike.
  • An opening tag inherits the provenance of its first content. Ctrl+click on a line carrying only an opening tag may therefore designate the instruction of the content that follows.
  • Highlights apply to the whole line, never to a range of columns: the Saxon-HE engine supplies only a line point. On a line carrying several instructions, the highlight does not say which one.
  • Template coverage is relative to the input document (§5.4). A template inlined by the optimiser may also appear as untriggered although its code really did run.
  • Absolute times are indicative: profiling instruments the engine, which costs a little. It is the relative differences between templates that count, and they are reliable.
  • The profiler writes no output: it measures, it does not produce. Use F5 to get the result file.

What next

Manual contents