gpt4 book ai didi

java - 我怎样才能更快?

转载 作者:行者123 更新时间:2023-12-04 05:37:55 27 4
gpt4 key购买 nike

我做了一个事件系统,但是,它太慢了。

问题是 map 中有多个条目我从未实际添加过。我不明白他们是如何到达那里的。

public class OrdinalMap<V> {

private final Map<Integer, V> map;

public OrdinalMap(Class<? extends Enum<?>> valueType, V virginValue) {
map = new HashMap<Integer, V>();
Enum<?>[] enums = valueType.getEnumConstants();
for (int i = 0; i < enums.length; i++) {
put(enums[i].ordinal(), virginValue);
}
}

public OrdinalMap(Class<? extends Enum<?>> valueType) {
this(valueType, null);
}

public V put(Integer key, V value) {
return map.put(key, value);
}

public V get(Object o) {
return map.get(o);
}

public Set<Entry<Integer, V>> entrySet() {
return map.entrySet();
}

}

我想让 dispatchEvent 更快(更少的迭代)。由于 registerListener 迭代次数过多

在所有其他优先级中都有事件处理程序方法,当它们不应该存在时。我不知道为什么会有,但我确定它在 registerListener 中。因为它们属于所有优先级,所以我必须使用此检查:
if (mapping.getKey().getAnnotation(EventHandler.class).priority().ordinal() == entry.getKey()) {

这使它变得更慢。
@Override
public void dispatchEvent(Event event) {
OrdinalMap<Map<Method, EventListener>> priorityMap = getRegistry().get(event.getClass());

if (priorityMap != null) {
CancellableEvent cancellableEvent = null;
boolean cancellable;
if (cancellable = event instanceof CancellableEvent) {
cancellableEvent = (CancellableEvent) event;
if (cancellableEvent.isCancelled()) return;
}

try {
for (Entry<Integer, Map<Method, EventListener>> entry : priorityMap.entrySet()) {
for (Entry<Method, EventListener> mapping : entry.getValue().entrySet()) {
if (mapping.getKey().getAnnotation(EventHandler.class).priority().ordinal() == entry.getKey()) {
mapping.getKey().invoke(mapping.getValue(), event);
if (cancellable && cancellableEvent.isCancelled()) return;
}
}
}
} catch (InvocationTargetException | IllegalAccessException e) {
e.printStackTrace();
}
}
}

@Override
public void registerListener(EventListener listener) {
for (Method method : listener.getClass().getMethods()) {
EventHandler handler = method.getAnnotation(EventHandler.class);
if (handler != null) {
Class<?>[] parameters = method.getParameterTypes();
if (parameters.length == 1) {
@SuppressWarnings("unchecked")
Class<? extends Event> event = (Class<? extends Event>) parameters[0];
EventPriority priority = handler.priority();

OrdinalMap<Map<Method, EventListener>> priorityMap = getRegistry().get(event);
if (priorityMap == null) {
priorityMap = new OrdinalMap<Map<Method, EventListener>>(EventPriority.class, (Map<Method, EventListener>) new HashMap<Method, EventListener>());
}

Map<Method, EventListener> methodMap = priorityMap.get(priority.ordinal());

methodMap.put(method, listener);
priorityMap.put(priority.ordinal(), methodMap);

getRegistry().put(event, priorityMap);
}
}
}
}

最佳答案

您正在使用 map ,因此请考虑使用这些好处而不是迭代所有条目

if (mapping.getKey().getAnnotation(EventHandler.class).priority().ordinal() == entry.getKey()) {

比较两个 hahmap 键以找到匹配项并不是一个好主意。

下面怎么样,我希望我没有犯任何思维错误
Set<Integer> priorityMapKeySet = priorityMap.keySet();
for (Map<Method, EventListener> mapping : priorityMap.values()) {
if (priorityMapKeySet.contains(mapping.getKey().getAnnotation(EventHandler.class).priority().ordinal())) {
mapping.getKey().invoke(mapping.getValue(), event);
if (cancellable && cancellableEvent.isCancelled()) return;
}
}

在这里你不再有外部 for 循环

我的错,没注意...

但想法是一样的,当使用 hashmaps/hashsets 时,应该总是尝试使用 get/contains 而不是迭代,为此需要设计注册表以使其成为可能

以下是否适合您的需求? (未经测试)
private final static class Registry {

private final static Map<String, Set<Integer>> prioritySetByEventMap = new HashMap<>();
private final static Map<String, EventListener> eventListenerByEventAndPriorityMap = new HashMap<>();
private final static Map<String, Method> methodByEventAndListenerMap = new HashMap<>();

public static Set<Integer> getPrioritySetByEvent(Class<Event> event) {
return prioritySetByEventMap.get(event.getName());
}

public static synchronized void registerEventByPriority(Class<Event> event, Integer priority) {
Set<Integer> ps = prioritySetByEventMap.get(event.getName());
if(ps == null) {
ps = new HashSet<>();
prioritySetByEventMap.put(event.getName(), ps);
}
ps.add(priority);
}

public static EventListener getEventListenerByEventAndPriority(Class<Event> event, Integer priority) {
String key = event.getName() + "-" + priority;
return eventListenerByEventAndPriorityMap.get(key);
}

public static synchronized void registerEventListenerByEventAndPriority(Class<Event> event, Integer priority, EventListener listener) {
String key = event.getName() + "-" + priority;
eventListenerByEventAndPriorityMap.put(key, listener);
}

public static Method getMethodByEventAndListener(Class<Event> event, EventListener listener) {
String key = listener.toString() + "-" + event.getName();
return methodByEventAndListenerMap.get(key);
}

public static synchronized void registerMethodByEventAndListener(Class<Event> event, EventListener listener, Method method) {
String key = listener.toString() + "-" + event.getName();
methodByEventAndListenerMap.put(key, method);
}
}


public void registerListener(EventListener listener) {
for (Method method : listener.getClass().getMethods()) {
EventHandler handler = method.getAnnotation(EventHandler.class);
if (handler != null) {
Class<?>[] parameters = method.getParameterTypes();
if (parameters.length == 1) {

Class<Event> event = (Class<Event>) parameters[0];

EventPriority priority = handler.priority();

Registry.registerEventByPriority(event, priority.ordinal());

Registry.registerEventListenerByEventAndPriority(event, priority.ordinal(), listener);

Registry.registerMethodByEventAndListener(event, listener, method);

}
}
}
}


public void dispatchEvent(Event event) {
Set<Integer> prioritySet = Registry.getPrioritySetByEvent((Class<Event>) event.getClass());

if (prioritySet != null) {
CancellableEvent cancellableEvent = null;
boolean cancellable;
if (cancellable = event instanceof CancellableEvent) {
cancellableEvent = (CancellableEvent) event;
if (cancellableEvent.isCancelled())
return;
}

try {

for(Integer priority : prioritySet) {

EventListener listener = Registry.getEventListenerByEventAndPriority((Class<Event>) event.getClass(), priority);

if(listener != null) {
Method m = Registry.getMethodByEventAndListener((Class<Event>) event.getClass(), listener);
if(m != null) {
m.invoke(listener, event);
if (cancellable && cancellableEvent.isCancelled()) {
return;
}
}
}
}

} catch (InvocationTargetException | IllegalAccessException e) {
e.printStackTrace();
}
}
}

关于java - 我怎样才能更快?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11694622/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com