EXSLT for MSXML
by Dimitre Novatchev
|
Pages: 1, 2, 3
Is XSLT Inefficient?
Today the prevailing opinion is that XSLT applications are quite inefficient as compared to applications written in a conventional programming language. Therefore, it would be interesting to see how this XSLT-based implementation compares to other implementations of EXSLT.
It was of particular interest how different EXSLT implementations behave with very large inputs. One of the tests was performed with all functions of the Sets module over a node set of 10000 nodes. The second test ran these functions on a much shorter node set consisting of 2000 nodes. I tested the Sets implementations of the following eight XSLT processors: Xalan C 1.5 ( C ), Saxon 6.5.2 (Java), Msxml4 (XSLT), JD (Java), .Net (C#), 4XSLT (Python), xsltProc/xsltLib ( C ), Xalan J 2.4.1 (Java).
I don't claim that the results are 100% correct or that XSLT processor X is much faster than an XSLT processor Y. I encourage readers are encouraged to perform their own tests. However, I believe that these results would be useful both to users and developers of XSLT processors -- in choosing a suitable XSLT processor that supports EXSLT or in further improving the EXSLT implementation of such a processor.
As can be seen from the results, exMSXML4 ran considerably faster than 5 of the 8 tested implementations, which were written in Java, Python, C#, and C.
exMSXML4 was slower only compared to Xalan C 1.5 and Saxon 6.5.2
(although it was faster than Saxon on set:leading() and
set:trailing() and faster than both Xalan C 1.5 and Saxon
6.5.2 on set:has-same-node()).
The actual tests are provided in the Appendix. They were run on a 1.7GHz Pentium 4 with 256MB of RAM. All results are in milliseconds.
The results are summarized in the two tables below:
Time Comparison between different implementations of EXSLT
| 1. With a node-set of 10000 nodes | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Implementation | Intersection | difference | leading | trailing | distinct | Has-same-node | Total | Average | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Xalan C 1.5 | 80 | 80 | 10 | 15 | 50 | 58 | 293 | 49 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Saxon 6.5.2 | 170 | 170 | 140 | 140 | 160 | 150 | 930 | 155 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| exMsxml 4 | 1391 | 1524 | 29 | 23 | 4468 | 46 | 7481 | 1247 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| JD | 3095 | 3635 | 170 | 140 | 12117 | 150 | 19307 | 3218 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| 4XSLT | 6840 | 7400 | 891 | 871 | 751 | 6930 | 23323 | 3887 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| .Net xslTransform | 5802 | 5832 | 22 | 22 | 10696 | 6558 | 28932 | 4822 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| xsltProc | 37674 | 40808 | 20549 | 20429 | 20830 | 44754 | 185044 | 30840 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Xalan J 2.4.1 | 2013 | 2003 | 181220 | 43653 | 1112 | 1122 | 231123 | 38520 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| 2. With a node-set of 2000 nodes | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Implementation | Intersection | difference | leading | trailing | distinct | Has-same-node | Total | Average | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Xalan C 1.5 | 15 | 13 | 1 | 1 | 10 | 10 | 50 | 8 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Saxon 6.5.2 | 31 | 30 | 30 | 20 | 30 | 20 | 161 | 27 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| exMsxml 4 | 72 | 75 | 11 | 9 | 238 | 14 | 419 | 70 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| .Net xslTransform | 115 | 115 | 12 | 11 | 368 | 140 | 761 | 127 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| JD | 140 | 160 | 80 | 80 | 370 | 100 | 930 | 155 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| 4XSLT | 460 | 460 | 150 | 150 | 140 | 471 | 1831 | 305 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| xsltProc | 430 | 430 | 210 | 210 | 250 | 570 | 2100 | 350 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Xalan J 2.4.1 | 921 | 901 | 6709 | 2733 | 832 | 871 | 12967 | 2161 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Conclusion
This article described a general way to obtain an instance of a non-creatable object by using a callback. I have shown how to build an efficient XSLT application by improving an algorithm step by step. I demonstrated several optimization techniques: binary search, DVC, using keys, and elimination of recursion. The test results show that this XSLT-based implementation of the Sets module of EXSLT is faster than five other implementations written in Python, Java, C, and C#.
Appendix -- the tests code
The two source xml documents, on which the tests were performed look like this:
nums10000.xml:
<Nums> <Num>1</Num> <Num>2</Num> <Num>3</Num> . . . . . . . . . <Num>9998</Num> <Num>9999</Num> <Num>10000</Num> </Nums>
Nums2000.xml:
<Nums> <Num>1</Num> <Num>2</Num> <Num>3</Num> . . . . . . . . . <Num>1998</Num> <Num>1999</Num> <Num>2000</Num> </Nums>
- Testing
set:intersection()-- testExsltIntersect.xsl:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:set="http://exslt.org/sets"> <xsl:output omit-xml-declaration="yes"/> <xsl:template match="/"> <xsl:variable name="v2" select="/*/*[. mod 2 = 0]"/> <xsl:variable name="v3" select="/*/*[. mod 3 = 0]"/> <xsl:variable name="vIntersect" select="set:intersection($v2, $v3)"/> <xsl:copy-of select="$vIntersect[1]"/> </xsl:template> </xsl:stylesheet>
- Testing
set:difference()-- testExsltDifference.xsl:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:set="http://exslt.org/sets"> <xsl:output omit-xml-declaration="yes" indent="yes"/> <xsl:template match="/"> <xsl:variable name="v2" select="/*/*[. mod 2 = 0]"/> <xsl:variable name="v3" select="/*/*[. mod 3 = 0]"/> <xsl:variable name="vDifference" select="set:difference($v2, $v3)"/> <xsl:copy-of select="$vDifference[1]"/> </xsl:template> </xsl:stylesheet>
- Testing
set:leading()-- testLeading.xsl:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:set="http://exslt.org/sets"> <xsl:output omit-xml-declaration="yes" indent="yes"/> <xsl:template match="/"> <xsl:copy-of select="set:leading(/*/*, /*/*[last()])[1]"/> </xsl:template> </xsl:stylesheet>
- Testing
set:trailing()-- testTrailing.xsl:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:set="http://exslt.org/sets"> <xsl:output omit-xml-declaration="yes" indent="yes"/> <xsl:template match="/"> <xsl:copy-of select="set:trailing(/*/*, /*/*[1])[1]"/> </xsl:template> </xsl:stylesheet>
- Testing
set:distinct()-- testEXSLTDistinct.xsl:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:set="http://exslt.org/sets"> <xsl:output omit-xml-declaration="yes" indent="yes"/> <xsl:template match="/"> <xsl:copy-of select="set:distinct(/*/*)[1]"/> </xsl:template> </xsl:stylesheet>
- Testing
set:has-same-node()-- testExsltSameNodes.xsl:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:set="http://exslt.org/sets"> <xsl:output omit-xml-declaration="yes" indent="yes"/> <xsl:template match="/"> <xsl:variable name="v2" select="/*/*[. mod 2 = 0]"/> <xsl:variable name="v3" select="/*/*[. mod 3 = 0]"/> <xsl:variable name="v4" select="/*/*[7]"/> <xsl:variable name="vbSame23" select="set:has-same-node($v2, $v3)"/> set:has-same-node(/*/*[. mod 2 = 0], /*/*[. mod 3 = 0]) = <xsl:text/> <xsl:copy-of select="$vbSame23"/> <xsl:text> </xsl:text> <xsl:text> </xsl:text> <xsl:variable name="vbSame24" select="set:has-same-node($v2, $v4)"/> set:has-same-node(/*/*[. mod 2 = 0], /*/*[7]) = <xsl:text/> <xsl:copy-of select="$vbSame24"/> </xsl:template> </xsl:stylesheet>
Share your questions or comments on this article in our forum.
(* You must be a member of XML.com to use this feature.)
Comment on this Article
| Titles Only | Titles Only | Newest First |
- Missing source?
2003-08-07 11:51:13 not right [Reply]
Out of sheer curiosity, I downloaded the source and tried to compile it, but gave up after I came across one error after another.
I am not a C programmer by trade, but I believe many projects on SourceForge are released in such a way so that they can be simply unzipped and compiled with little or no problems.
Whilst I dug around the source for clues, I discovered that the very stylesheets described in the article are not part of the source. On my hunt for the missing files and possibly some instructions, I discovered (by simply opening the command line executable in a text editor) the missing stylesheets but again not readily available as part of any of the source on SourceForge.
I think the author needs to release the source in a more user friendly manner before anyone can begin to rely on the compiled versions as they stand.
- Missing source?
2003-08-11 06:33:37 Dimitre Novatchev [Reply]
"not right" wrote:
> Out of sheer curiosity, I downloaded the source
Which source? There are two projects. I assume that you are talking about EXSLT.dll
> and tried to compile it, but gave up after I
> came across one error after another.
How did you try to compile the source?
> I am not a C programmer by trade,
This most probably is the source of your difficulties.
> but I believe many projects on SourceForge are > released in such a way so that they can be
> simply unzipped and compiled with little or
> no problems.
This is exactly the case.
More precisely:
1. The exsltdll.zip archive must be extracted preserving the directory structure.
2. MS Visual Studio 6.0(VC++ 6.0) must be started and the workspace (EXSLT.dsw) must be opened. This is the only .dsw file, so a VC++ programmer does not have any difficulty in building the project.
3. From the "Build" menu select "Rebuild all"
This is everything necessary to build the project and there have been no problems raised since the beginning of June, two months ago, when this archive was first put in sourceforge.net.
>
> Whilst I dug around the source for clues, I
> discovered that the very stylesheets described > in the article are not part of the source.
Not true -- they are contained in the resource files of the project.
In the Workspace window (View->Workspace) click on the Resource View tab. The stylesheets can be viewed as string resources of the project.
> On
> my hunt for the missing files and possibly some > instructions, I discovered (by simply opening
> the command line executable in a text editor)
> the missing stylesheets but again not readily
> available as part of any of the source on
> SourceForge.
This must be a joke -- the stylesheets are not part of exMsxsl.exe
They are part of EXSLT.dll, which is not a command-line executable.
As explained above, the stylesheets are available in source and can be viewed in resource view.
Also, the stylesheets were published in a pretty-printed format in the article itself. This *is* the recommended source for reading by a human reader as opposed to building the project automatically by the Visual Studio 6 IDE.
>
> I think the author needs to release the source > in a more user friendly manner before anyone
> can begin to rely on the compiled versions as
> they stand.
As explained above, the stylesheets are part of the source.
I encourage anyone to build the project.
Although you are the only one, who has experienced difficulties in building the project (which is understandable for a person without experience with the Visual Studio 6 VC++ IDE), I would be happy to help in case you continue to have problems in understanding the build process.
Please, contact me offline, in the highly unlikely case if you still cannot build the project. Providing a real name would certainly be helpful.
Cheers,
Dimitre Novatchev.
- re compiling
2003-08-11 13:05:27 James Fuller [Reply]
FYI: compiled source code 1st time around, seemed straight forward to me. nice article and great to see someone solve this irratating problem.
I was going to show everyone the ugly hack I did a year or so ago, deploying EXSLT via a GET based SOAP weservice, and calling it via complicated document() calls. But now I can just use this ! nice work.
ps: I was pushing around the code a bit, and found some pre-existing enabled/non-enabled breakpoints, confused me for but a moment
- re compiling
- Missing source?




