Usually, an XML file is parsed as a whole and held in memory as XDM. So, I guess that by
than parsing the tree multiple times
you actually meant accessing the internal representation of the XML input multiple times. The figure below illustrates this, we are talking about the source tree:
(taken from Michael Kay's XSLT 2.0 and XPath 2.0 Programmer's Reference, page 43)
Likewise, xsl:variable
creates a node (or, more precisely, a temporary document) that is held in memory and that needs to be accessed, too.
Now, what exactly do you mean by optimisation? Do you mean the time it takes to perform the transformation or CPU and memory usage (as you mention "resources" in your question)?
Also, performance depends on the implementation of your XSLT processor of course. The only reliable way of finding out is to actually test this.
Write two stylesheets that differ only in this regard, that is, are identical otherwise. Then, let both of them transform the same input XML and measure the time they take.
My guess is that accessing a variable is faster and it is also more convenient to repeat a variable name than repeating full paths as you write code (this is sometimes called "convenience variables").
EDIT: Replaced with something more appropriate, as a response to your comment.
If you actually test this, write two stylesheets:
Stylesheet with variable
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes"/>
<xsl:template match="/root">
<xsl:copy>
<xsl:variable name="var" select="node/subnode"/>
<subnode nr="1">
<xsl:value-of select="$var"/>
</subnode>
<subnode nr="2">
<xsl:value-of select="$var"/>
</subnode>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
Stylesheet without variable
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes"/>
<xsl:template match="/root">
<xsl:copy>
<subnode nr="1">
<xsl:value-of select="node/subnode"/>
</subnode>
<subnode nr="2">
<xsl:value-of select="node/subnode"/>
</subnode>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
Applied to the following input XML:
<root>
<node>
<subnode>helloworld</subnode>
</node>
</root>
EDIT: As suggested by @Michael Kay, I measured the average time taken in 100 runs ("-t and -repeat:100 on the Saxon command line"):
with variable: 9 ms
without variable: 9 ms
This does not imply that the result is the same with your XSLT processor.