thymeleaf/thymeleaf — pull request #320 by jkuipers (2014-10-14 08:23:04+00:00)
Title: WrappingVariablesMap

Here's another optimization (in addition to the one in #318, but completely independent), which gets rid of the constant copying of the attributes in a WebVariablesMap for every node resulting in many expensive calls to WebVariablesMap#entrySet from inside createEvaluationRoot(). I've introduced a WrappingVariablesMap, which basically masks a given VariablesMap which stays read-only and allows adding contents without the need to copy the whole original map.
It's not strictly conformant with respect to the java.util.Map contract, but neither is the WebVariablesMap. At least I've documented the deviations ;)

In my local testing this patch saves about 200 milliseconds for one view render action by preventing almost 2000 full copies of a WebVariablesContext's contents from being made. This is after applying the fix in #318 first BTW, this should save even more without that patch.
In my Spring app the requests contain about a hundred request attributes when rendering the view, while the added contents typically seems limited to a handful of additional entries, so only keeping track of those handful is much more efficient, both in terms of CPU and memory being used.
Note that I have assumed here that the Thymeleaf code doesn't rely on VariablesMap.keySet(), .values() and .entrySet() returning a mutable collection supporting directly modifying the underlying map and doesn't need to remove variables from the original mao . I feel pretty confident about that assumption given the way that WebVariablesMap works, but please check this for correctness.