PMD lazy-loading optimization

10 Sep 2005

A bug report on PMD's forums got me thinking about a way to make XPath rule processing (*) a bit faster.

A typical AST node has about a dozen attributes like "begin line", "end line", and so on. These are accessible via the XPath integration, so you can do something like //MethodDeclarator[@BeginLine=5] to get the method declaration on line 5. Anyhow, whenever a single attribute is queried on a node, all the attribute values are fetched via Method.invoke(). So even though only one value was being used, we were fetching all the values. This resulted in PMD making about 110K reflection calls in a run of the basic ruleset on the java/lang packages.

After some refactoring, the Attribute object now fetches the value only when the Attribute.getValue() method is actually called. This lazy loading cut the number of reflection calls down to about 10K for the basic ruleset run on java/lang - an order of magnitude fewer!

Most importantly, lazily loading these attribute values cuts total run time by about 8 percent. Good times!

(*) Props to Daniel Sheppard for envisioning and implementing this feature originally! Way back in March 2003, so it 'twas.