I saw using a profiler, that OgnlValueStack.findValue(String) gets called about a thousand times during rendering a page. Most of the calls are coming from ScopesHashModel.
All freemarker templates contain a lot of references to e.g. "parameters". This variable is evaluated in ScopesHashModel over and over again, which takes about 10% time of total page load.
I think we can assume, that the top-level objects on the value stack will not change during rendering a single struts2 tag. So with a little caching, we can eliminate most of the findValue method calls.
In my application I tested this modification and didn't notice any side effects or bugs. The OgnlValueStack.findValue(String) calls on a test page went down from a thousand to a hundred. This improved overall page rendering time from about 400ms to 360ms.
Patch is attached.
Please review it.