Improve performance of ComparisonSpec

Calling Comparison.getDifferences() is expensive for large models, so
with this change we introduce caching for the difference list. Given
there is already a DiffCrossReferencer attached, we can detect
structural changes that require flushing the cached differences.
Unfortunately the old implementation doesn't return an unmodifiable
result (and existing tests make use of that assumption), so this new
implementation also flushes the cached result when the result itself is
modified. Note the list is cached only if there is already a diff cross
reference attached to avoid unnecessary caching during building the
differences.

The getMatch method is generally called O(n^2) times with a significant
overall impact on the cost of merging, so it's important this method be
as fast as possible. The overhead of this method can be reduced by
avoiding the overhead of creating an iterator, i.e., by making use of
the fact that the cross referencer always returns a list.

The getInverseReferences is also called O(n^2) times. The overhead of
processing the diffs looking for resource attachment changes is a very
large portion of the cost of this method. This cost can be reduced by
avoiding proxy resolution, casting, and iterator overhead. Resource
attachment changes are relatively rare, so best not even to
create a list if there are none.

Of course getInverseReferences calls addSettingEObjectsTo so best to
make that method as efficient as possible too, i.e., we can avoid the
cast to Diff by casting the list itself allow any object to be added;
that cast is free because we're not actually casting to a different raw
type.

Change-Id: I4cb634128dcca9c0016a1eedf381895220d0c191
Signed-off-by: Philip Langer <planger@eclipsesource.com>
1 file changed