I am trying to stream the identity in XSLT, using Saxon.
I've done it in two different ways:
1) cat the xml file and pipe to Saxon
2) take the xml as input

3) and 4) as above, but without the streaming directive;
so, 3) and 4) run from memory.

What confuses me:
3) and 4) are *faster* than the streaming execution.
How can that be??

I find it also confusing that for streaming,
memory consumption increases by 50%
when I run from the cat-pipe, as when the file name is given.
Can this be explained? (-- it is faster though) -- see the numbers below.

Moreover, if I use another streaming tool, such as GCX (written in C++)
and run the identity (written in XQuery) then this is *much* faster; it takes
less than half of the time of Saxon.
Is this only due to the fact that Saxon is written in java and uses a java
XML parser?

I'm running the Saxon EE (9.5) edition with an evaluation copy.
I use this style sheet:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="3.0">
  <xsl:mode streamable="yes"/>
  <xsl:template match="@*|node()">
      <xsl:apply-templates select="@*|node()"/>

I ran in four different ways:

(1) cat 100M.xml | java -jar saxon9ee.jar .... -s:/dev/stdin

This takes 23.5s and takes 18Mb memory on my machine.

(2) java -jar .. -s:100M.xml

This takes 24.4s and 12.6Mb memory.

(3) I remove the "streamable=yes" line above and run non-streamed,
using the cat and stdin.

This takes 16.3s and uses 310M of memory.

(4) Then I run without cat but with the file name given to saxon, and this
takes 13.8s and 368M of memory.

As a comparison: GCX will use 2.6M of memory and stream the
identity (in XQuery) in 10s.

Thanks for your help,