Bug 88653 [Commands] performance: 50% of perspective switch in ParameterizedCommand.equals()
Build: I20050315 Setup: 1) Workspace with three projects, org.eclipse.jdt.core, org.eclipse.swt, and org.eclipse.swt.win32 2) Editor open on org.eclipse.jdt.internal.compiler.parser.Parser.java 3) Default Java perspective and Resource perspective open My test was to switch between the two open perspectives about five times using Ctrl+F8. The profiler showed 50% of the time in ParameterizedCommand.equals() and in the methods called by that equals implementation (Util.equals() and Command.equals()). The main problem is probably in the number of times this method is called (about 1.6 million times). This seems to be caused by a large number of property change events: ExternalActionManager$CommandCallback.bindingManagerChanged is called 30 times. This in turn calls ActionContributionItem$1.propertyChange, which is called 4787 times. The number of method calls explodes as you go down the call stack, until the equals method that is called 1.6 million times. I will attach profiler output to show more details. If the number of change events can't be reduced, it looks like the implementation of ParameterizedCommand.equals() can be made faster by first comparing the cached hash code. Only if the hash codes are the same does it need to do the remainder of the equality testing.
bundles/org.eclipse.core.commands/src/org/eclipse/core/commands/Command.java
/**
 * <p>
 * A command is an abstract representation for some semantic behaviour. It is
 * not the actual implementation of this behaviour, nor is it the visual
 * appearance of this behaviour in the user interface. Instead, it is a bridge
 * between the two.
 * </p>
 * <p>
 * The concept of a command is based on the command design pattern. The notable
 * difference is how the command delegates responsibility for execution. Rather
 * than allowing concrete subclasses, it uses a handler mechanism (see the
 * <code>handlers</code> extension point). This provides another level of
 * indirection.
 * </p>
 * <p>
 * A command will exist in two states: defined and undefined. A command is
 * defined if it is declared in the XML of a resolved plug-in. If the plug-in is
 * unloaded or the command is simply not declared, then it is undefined. Trying
 * to reference an undefined command will succeed, but trying to access any of
 * its functionality will fail with a <code>NotDefinedException</code>. If
 * you need to know when a command changes from defined to undefined (or vice
 * versa), then attach a command listener.
 * </p>
 * <p>
 * Commands are mutable and will change as their definition changes.
 * </p>
 * 
 * @since 3.1
 */
public final class Command extends NamedHandleObject implements Comparable {