When the handler iterator is assembled for an incoming event, the handlers bound directly to the event class are retrieved from the binding map in constant time. However, all bindings still have to be tested in case they are polymorphic and compatible with the event class, resulting in linear time complexity with respect to the amount of handler bindings.
Given a large amount of registered listeners, this process can take up a considerable amount of time during every dispatch, so caching would be beneficial here. The cache would be a
Map<Class<?>, NavigableSet<EventHandler>>, with the keys being event classes and the values being sorted sets of the corresponding event handlers.
When a new binding is created, the cache has to be updated for both the target class and all of its super classes and interfaces, which can be achieved by iterating over the cache and testing for assignment compatibility. This operation makes listener registration slower, but the benefits in dispatch speed should outweigh this even for two dispatches with the same event type.
When an existing binding is removed because its declaring listener is removed, the binding has to be removed from the cache as well. Clearing the listeners also requires this action, although the cache can just be emptied in this case.
Deleting a branch is permanent. It CANNOT be undone. Continue?