The V1R10 XML Parser, C++ Edition demonstrates improved performance over the V1R9 XML Parser, C++ Edition in most parsing scenarios. The results below were generated by measuring performance when parsing a set of XML documents of various sizes and complexities. The number of CPU cycles required to parse a single byte was determined by calculating the geometric mean of the per byte costs for all benchmark documents.
The XML Toolkit V1R10 can perform both validating and non-validating parsing, and can provide opportunities for offload parsing to z Application Assist Processors (zAAPs). Significant raw performance improvement can be achieved for non-validating parsing. The performance of the validating parser depend greatly on size and complexity of the schema and the document being parsed. The following chart shows the performance boost from using z/OS XML System Services for non-validation parsing.
For details on use of the new z/OS specific parser classes, refer to the User's Guide.
Parsing and transformation are CPU intensive activities. It is important to make efficient use of these technologies. The hints and tips below provide suggestions for building better performing parsing and transformation applications.
The processing required to prepare DTD and schema grammars for use in validation is expensive. It is possible to reduce the CPU time needed to validate an XML document by pre-parsing and caching DTD and schema grammars. These pre-parsed grammars may then be reused for subsequent validation. Performance enhancement due to reuse of pre-parsed grammars will vary depending on the size and complexity of the XML document and the schema or DTD. Sizable improvements may be expected when relatively small, simple documents are validated with cached grammars.
Turn validation off when not needed and avoid DOCTYPE clauses
Turn validation off if you don't need it. Also, avoid using a DOCTYPE clause if you don't plan to validate. DOCTYPE clauses are not required and should not be used unless there is a strong functional reason to do so. The parser will, by default, read the DTD if the DOCTYPE line is specified, even when not validating.
Use special scanner when document validation type is known
The XML4C parser uses a default document scanner IGXMLScanner, which handles all types of XML documents, whether well-formed only or when conforming to a DTD or schema. If the type of validation is known ahead of time, performance can be improved by specifying a scanner particular to the validation being done. These scanners are: WFXMLScanner for well-formedness checking only, DGXMLScanner for DTD validation only, and SGXMLScanner for schema validation only. Although, the default scanner performed slightly better over DGXMLScanner for our tests, this may vary with the size and complexity of the document. The test results were generated by measuring performance when parsing a set of XML documents of various sizes and complexities. Particularly for well-formedness checking or DTD validation, significant improvement may be expected by the use of these special scanners.
Note: Special scanners are supported by the XML4C parser only. They are not supported when invoking z/OS XML System Services as the underlying parsing technology.
For best validating performance, use a DTD instead of a schema
Schemas provide extensive capability for sophisticated validation. Our tests have shown, however, that DTD's are more efficient than schemas when performing equivalent validating tasks. If your application does not require the added functionality provided by schemas, use a DTD to validate your XML documents.
Use external entities and external DTD's only when necessary
External entities and external DTD's result in extra file opens and the transcoding setup they require is expensive.
Avoid multiple parses of the same document
There may be times when it would be convenient to parse the same document more than once in the course of a single transaction. Duplicate parses are expensive. Avoid the overhead of additional parses by storing the results of the initial parse in a format which may be efficiently accessed at a later time.
Reuse the initialized parser
When parsing a small document, most of the CPU time is spent on parser initialization. You should, therefore, avoid instantiating a new parser every time you parse. Instead, create the parser once, and reuse the parser instance. A pool of reusable parser instances is a good idea if you have many threads parsing at the same time.
Avoid unnecessary document conversions
The XML parser will convert your document to Unicode before parsing. Avoid unnecessary overhead by preventing additional document conversion prior to the parse.
Reduce character count
Try to reduce your character count; smaller documents are parsed more quickly. Avoid unnecessary use of white space as spaces, tabs, and line feed characters must also be parsed.
Pre-normalize line end characters
Compliance with the XML specification requires the parser to normalize line end characters by replacing the two character sequence x'0D0A' and any occurrence of a solitary x'0D' with the single character x'0A'. Reduce parsing costs by constructing XML documents using x'0A' to indicate the end of a line of text.
Avoid using default attributes
Avoid the use of default attributes. Attributes are associated with elements within a document. A purchase order element might, for example, contain a status attribute set to "in process", "shipped", or "billed". If, in your DTD, you specify a default value for the attribute rather than explicitly assigning a value in your XML document, processing will be slower.
If possible, use SAX instead of DOM, especially when parsing large documents.
Parsing with SAX is more efficient and requires less memory.
Store your XML documents in the z/OS or OS/390 UNIX HFS
It is more efficient to store your XML documents in the z/OS or OS/390 UNIX HFS than in an MVS data set, such as SAM or PDS.
If you are using the z/OS specific parser classes, use the following performance recommendations.
When considering the use of z/OS specific parser classes, comparative performance measurements should be taken on representative document types in order to effectively compare raw performance. Also, analysis of the potential benefits of using the z/OS specific parser classes should include both raw performance comparison and the value of the ability to re-direct processing to zAAP specialty engines.
If your applications are compiled with the XPLINK option, use the XPLINK version of the XML4C parser.
Due to the performance overhead involved in communication between XPLINK and non-XPLINK compiled code, most non-XPLINK applications will perform better when the non-XPLINK version of the parser is used.
Use the new DOM bindings
The new DOM implementation performs significantly better than the old DOM especially in multi-threaded applications.
Disable namespace support if not needed
The use of namespaces adds an additional level of complexity to parsing. If you know your application will not be parsing documents that contain specific references to namespaces, disable namespace support.
Be careful when using getElementsByTagname("*").getLength()
This method walks the entire DOM tree to count the number of elements. If your DOM is large, this can be expensive.
Pass fully qualified pathnames
If your documents reside in the z/OS and OS/390 UNIX HFS, you will achieve a small improvement by passing the fully qualified pathnames to the XML parser.
Optimize your Language Environment parameters
Make sure that you optimize your Language Environment parameters. Language Environment parameters can be specified in JCL for batch environments or STC environments, or they can be passed to a program running under a z/OS or OS/390 UNIX shell in the CEE_RUNOPTS environment variable. The important parameters to specify are HEAPP(ON), LIBS(1K,1K,Keep), and STOR(,,,8). You may also need to override the sizes of HEAPS and STACKS if more storage is required.
Follow z/OS and OS/390 UNIX, C/C++, and Language Environment guidelines
Follow general z/OS and OS/390 UNIX tuning guidelines and make sure that the C/C++ and Language Environment runtime libraries are configured in LPA. You may also want to keep the XML parser and ICU component libraries in LPA. This will avoid program load from DASD each time the parser is invoked.
If your applications are compiled with the XPLINK option, use the XPLINK version of the XSLT4C processor (and XML4C parser).
Due to the performance overhead involved in communication between XPLINK and non-XPLINK compiled code, most non-XPLINK applications will perform better when the non-XPLINK versions of the parser and transformer are used.
Compile the stylesheet once and then reuse it
If your application will be using the same stylesheet to transform multiple XML documents, compile the stylesheet once and reuse it for subsequent transformations. The CompileStylesheet sample shipped with the C++ XSLT processor demonstrates how to compile a stylesheet and use the compiled version to transform an XML document.
Check heap and heap pool usage and adjust settings if necessary
The performance of some transformations can be significantly improved by tuning heap and heap pool allocations. Use the Language Environment HEAPPOOLS(ON) and RPTSTG(ON) run-time options to check heap and heap pool usage. If necessary, follow the recommended procedure in the z/OS Language Environment Programming Guide to adjust heap and heap pool settings. (Be sure to set RPTSTG(OFF), the default setting, once tuning is complete as program performance can be severely degraded by the collection of storage report data.)