Bug 136763 Performance improvements to BindingManager
Build id: I20060413-0010 One of our performance tests that still shows significant regression is opening editors. With profiling I found that 0.8% of that time is in Collections.unmodifiableMap(...) called by three methods in BindingManager. Another 0.15% is from instantiating new TrigerSequence[0] in three locations in BindingManager. In the first case, the creation of an immutable map is completely unnecessary - the methods are private, the maps are never exposed across API boundaries, and there is never any risk that the maps will be modified. The creation of empty TriggerSequence arrays can also be avoided with a singleton. I will attach a patch that collectively saves about 1% of the total editor startup time (elapsed time as measured by sampling profiler). These are very simple and safe fixes that I recommend considering for RC2.
bundles/org.eclipse.jface/src/org/eclipse/jface/bindings/BindingManager.java
* 
	 * @param bindings
	 *            The bindings which all match the same trigger sequence; must
	 *            not be <code>null</code>, and should contain at least two
	 *            items. This collection should only contain instances of
	 *            <code>Binding</code> (i.e., no <code>null</code> values).
	 * @param activeContextTree
	 *            The tree of contexts to be used for all of the comparison. All
	 *            of the keys should be active context identifiers (i.e., never
	 *            <code>null</code>). The values will be their parents (i.e.,
	 *            possibly <code>null</code>). Both keys and values are
	 *            context identifiers (<code>String</code>). This map should
	 *            never be empty, and must never be <code>null</code>.
	 * @return The binding which best matches the current state. If there is a
	 *         tie, then return <code>null</code>.
	 */
	private final Binding resolveConflicts(final Collection bindings,
			final Map activeContextTree) {
		/*
		 * This flag is used to indicate when the bestMatch binding conflicts
		 * with another binding. We keep the best match binding so that we know
		 * if we find a better binding. However, if we don't find a better
		 * binding, then we known to return null.
		 */
		boolean conflict = false;
		final Iterator bindingItr = bindings.iterator();
		Binding bestMatch = (Binding) bindingItr.next();
		/*
		 * Iterate over each binding and compare it with the best match. If a
		 * better match is found, then replace the best match and set the