Improve performance of equality helper

In a model with several 100,000 diffs, the matchValues method might well
be called 100,000,000 times so absolutely anything we can do to make
this faster has a highly significant impact.

As previously recognized, this method is often called repeatedly with
the same first object, so caching the match associated with that first
object can reduce match lookup by as much as 99%.  But even with a
cached match, the calls to getLeft, getRight, and getOrigin are still
significantly expensive because they do proxy resolution. Unfortunately
we can't simply cache the results, because the merging process in some
cases modifies these values. So most efficient and ideal would be if
the Match implementation has a method for comparing the argument against
the three values, without proxy resolution. For this purpose
MatchSpec.matches is added and the EqualityHelper assumes the Match is
implemented by MatchSpec, using that type as the cached match. This
cached value doesn't need to be a weak reference because the
equality helper is an adapter of the Comparison, so is not likely to
outlive the Comparison's matches.

Also, getTarget must repeatedly cast to Comparison, it's best we do this
just once when the target is set.

With the changed implementation, the cached match is used already in
matchingValues(Object, Object) so that even the two instanceof tests and
the two casts can be avoided, i.e., a 25% overhead for the "matches the
cached match" case. Note how the signature of the MatchSpec.match method
facilitates these non-EObject calls. The cache is of course computed by
matchingEObjects(EObject, EObject) where the actual lookup of a match
takes place.  The FeatureMap case is also slightly improved, i.e., avoid
fetching the values if the keys are different.

The old caching mechanism is removed.

Change-Id: I4f06f7c2b238ab5d47bd00c95a3cf2d3cca1abb5
Signed-off-by: Philip Langer <planger@eclipsesource.com>
2 files changed