SPEL Implementation

Nathan Abramson (arista@atg.com)

Overview

This distribution contains an implementation of the Simplest Possible Expression Language (SPEL) for the JSTL. In addition to the implementation, the distribution contains regression tests for the parser and evaluator, and a simple performance test.

The distribution contains the following directories and files:

Implementation Notes

Regression Tests

There are two sets of automated regression tests - the first tests the parser, and the second tests the full evaluator. In both cases, the tester takes an input file containing expressions to be parsed or evaluated, processes each expression, and writes the results or errors to an output file. The output file can then be compared against an expected output file to see if any regression has occurred.

In both cases, input lines that are blank or start with "#" are copied to the output file without interpretation. This allows comments to appear in the output file, which can aid in debugging.

Parser tests

The parser test input file is found at src/org/apache/taglibs/jsptl/lang/spel/test/parserTests.txt. Each line represents an expression to be parsed - the expression is parsed, and printed back out in the evaluator's "canonical form". For example, in the canonical form, all Strings are enclosed by double quotes, all names are prefixed by a scope operator ":", etc.

The expected outputs are found at src/org/apache/taglibs/jsptl/lang/spel/test/parserTestsExpectedOutput.txt.

The parser tests can be run like this:

The {expectedOutputFile} is optional - if supplied, the test will compare the ouput file with the expected output file and print whether the test passed or failed.

Evaluation tests

For the evaluation test, a "dummy" PageContext was created containing some beans with properties in various scopes. That PageContext is created in the "createTestContext" method of src/org/apache/taglibs/jsptl/lang/spel/test/EvaluationTest.java.

The evaluation test input file is found at src/org/apache/taglibs/jsptl/lang/spel/test/evaluationTests.txt. Each line represents an expression to be parsed, followed by a line specifying the expected type - the expression is parsed, and the resulting value is printed along with its class.

The expected outputs are found at src/org/apache/taglibs/jsptl/lang/spel/test/evaluationTestsExpectedOutput.txt.

The evaluation tests can be run like this:

The {expectedOutputFile} is optional - if supplied, the test will compare the ouput file with the expected output file and print whether the test passed or failed.

Optimizations

Because expression evaluation could conceivably make up a large portion of a JSP's rendering time, a great deal of emphasis was placed on performance. The following performance optimizations were used:

Performance Tests

The distribution includes a single performance test which evaluates an expression many times. The expression is:

To test for synchronization bottlenecks, the test spawns several threads which simultaneously evaluate the expression many times.

The test then runs again, but evaluates the expression "by hand" using direct API calls - i.e., pageContext.getAttribute(...).getBean1().getInt1 () < 24. So the performance test essentially determines the cost of using an expression instead of an rtexprvalue.

The test is run like this:

The initial results are encouraging - running 20 threads over 100000 iterations/thread, a ThinkPad 600E could do ~50000 iterations/second using the evaluator, and ~110000 iterations/second using the API calls. So using the API calls in this example is only twice as fast as using the evaluator, which means that the expression language introduces a significant, but not severe performance penalty.

$Change: 181170 $$DateTime: 2001/06/26 08:09:32 $$Author: shawn $