我们的传统应用程序被困在一个可怕的框架中(好吧,我会命名,它是Tapestry 4),涉及最简单的EventListeners
(〜100,000)操作。我猜这已经超出了javax.swing.event.EventListenerList
曾经处理过的范围,而在这个不幸的使用案例中,它给我们带来了一些令人讨厌的性能问题。为什么没有更换EventListenerList? (或者:替换它有什么缺陷?)
我花了几个小时以下掀起了相当幼稚HashMap/ArrayList
为基础的替代,它的大规模更快几乎在每一个方式:
新增5名听众:
EventListenerList
>2秒EventListenerMap
〜3.5毫秒
发生火灾事件至50,000个听众:
EventListenerList
0.3-0.5毫秒EventListenerMap
0.4-0.5毫秒
删除50000个听众(一次一个):
EventListenerList
>2秒EventListenerMap
〜 280毫秒
发火可能只是一头发较慢,但修改速度更快。无可否认,这个框架使我们处于病态的状况,但它似乎仍然很久以前就可以替代EventListenerList
。显然公共API存在问题(例如,它暴露了其原始内部状态数组),但除此之外肯定还有更多。也许有多线程的情况下,EventListenerList
更安全或更高性能?
public class EventListenerMap
{
private final ReadWriteLock lock = new ReentrantReadWriteLock();
private final Lock readLock = lock.readLock();
private final Lock writeLock = lock.writeLock();
private Map<Class, List> llMap = new HashMap<Class, List>();
public <L extends EventListener> void add (Class<L> listenerClass, L listener)
{
try
{
writeLock.lock();
List<L> list = getListenerList(listenerClass);
if (list == null)
{
list = new ArrayList<L>();
llMap.put(listenerClass, list);
}
list.add(listener);
}
finally
{
writeLock.unlock();
}
}
public <L extends EventListener> void remove (Class<L> listenerClass, L listener)
{
try
{
writeLock.lock();
List<L> list = getListenerList(listenerClass);
if (list != null)
{
list.remove(listener);
}
}
finally
{
writeLock.unlock();
}
}
@SuppressWarnings("unchecked")
public <L extends EventListener> L[] getListeners (Class<L> listenerClass)
{
L[] copy = (L[]) Array.newInstance(listenerClass, 0);
try
{
readLock.lock();
List<L> list = getListenerList(listenerClass);
if (list != null)
{
copy = (L[]) list.toArray(copy);
}
}
finally
{
readLock.unlock();
}
return copy;
}
@SuppressWarnings("unchecked")
private <L extends EventListener> List<L> getListenerList (Class<L> listenerClass)
{
return (List<L>) llMap.get(listenerClass);
}
}
+1疯狂(iest)这个月的问题,Q关于(对于最简单的操作)是每一个步骤都是单独的,或者它们被链接在树上或信号量上,如果是,那么另一个疯狂的(iest)建议,使用EventHandler和在运行时以String的形式建立路径,那么可能不需要在内存中保存一堆方法,phaaa我喜欢这个想法,这来自你的问题,让RPG永远活着(然后同样疯狂的无尽的代码) – mKorbel
你有没有在相对射击时间错字?你报告说,你的实现可能会“在0.4_milliseconds_下变慢”,而在EventListenerList中变为0.3_seconds_。 –
是的,这是一个错字,谢谢! –