maven-helper: point out invalid subcommands

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Add a helper for performance benchmarking

We often encounter the situation where a list of similar operations needs
to be sped up, and we need to find the most promising candidate quickly.
For example, when the startup of a context is slow, there are typically
only very few services dominating the time, and they are the best targets
for optimization.

The Timing helper makes it easy to find out those candidates by
accumulating a list of items with durations and reporting a sorted list
when the report() method is called.

The helper lives in src/test/java/ to avoid tainting the official
scijava-common API with it; that way, we can easily adapt it to new needs
or even break backwards-compatibility without having to worry about
bumping the version. In Eclipse, you can still use it because Eclipse is a
bit challenged with class path scopes: it simply mooshes all dependencies
together, including 'test' and 'compile' scoped ones, anyway.

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Timing: fix getCaller()

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Timing: add more convenience

Now it is sufficient to call the reset() method to reset the current
timing to 0, and you can call report(null) to make debugging easier
when the file name and line number are sufficient for the performance
benchmarking.

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
More convenience methods in Timing

Now you can perform performance benchmarks by adding

	final Timing timing = Timing.start(condition);
	...
	Timing.tick(timing);
	...
	Timing.tick(timing);
	...
	Timing.tick(timing);
	...
	Timing.stop(timing);

The stop() method will measure the last tick, order all the individual
steps (i.e. between ticks) by time and output a sorted list.

All of this only happens if the condition is true, which is really
convenient if you want to benchmark a method only for a given parameter.

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Move Timing out of src/test/

Required for Maven...

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Speed up ObjectIndex#add, part one

Instead of obtaining the complete class/interface hierarchy for ever
item we add, we can do that once per class; the next time we add an
item of the same class, we'll have the list already.

This shaves off around 10-15% of ImageJ's DefaultCommandService's
initialization.

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Speed up ObjectIndex#add, part two

Instead of looking up the list for every interface implemented by the
current item to add, we cache pre-calculated lists for every class
we encountered.

This shaves off another 5-10% of ImageJ's DefaultCommandService's
initialization.

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
EventService: do not use AWT's event queue for publishLater()

EventQueue.invokeLater consumes a whopping 100ms here, while a simple
spawned thread only consumes 3ms. Quite a difference.

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
ObjectIndex: support PluginIndex better

We used to require overriding the add() method for only one reason:
the type by which the objects are indexed in PluginIndex are not
obtained by getClass(), but by getPluginType().

This suggests that the base class actually needs a more flexible way
to obtain the types by which to index, so let's do that instead.

This will help with the upcoming performance enhancements which will
bypass the add() method completely for SortedObjectIndex' addAll().

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Try to speed up the SortedObjectIndex further

Rather than adding things blindly to several typed lists which are all
supported to be sorted already, only to sort them again in the end,
let's

- sort the elements to be added

- make sub-lists of the sorted list for the individual typed lists

- merge the sorted lists in O(n)

instead.

While at it, we should not iterate the elements of HashSets with
supposedly immutable contents over and over and over again. Let's make
performant arrays from them as soon as we generated the sets.

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Speed up loading the services by publishing the ServicesLoadedEvent lazily

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
DefaultEventBus: avoid publishing events nobody is interested in

The AWT EventQueue is really slow: EventQueue.invokeAndWait() can take
up to 30x as long as creating a new thread and starting it on the
provided Runnable.

If there is not even a subscriber to the event we are about to send,
let's just not bother.

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Merge branch 'speed-up-context'

This branch intends to accelerate context initialization. It manages
to shave off abit more than a third second of almost two seconds
startup time in ImageJ (this is already after optimizing SCIFIO to
load the formats lazily).

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
release-version: die when maven-helper could not be run

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>