Updated timing code for new event system

By: Tahg <tahgtahv@gmail.com>
This commit is contained in:
Bukkit/Spigot 2012-01-16 15:03:41 -05:00
parent b19803ff66
commit 05b6ad92d1
8 changed files with 169 additions and 33 deletions

View File

@ -4,11 +4,16 @@ import org.bukkit.Bukkit;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import org.bukkit.event.Event;
import org.bukkit.event.HandlerList;
import org.bukkit.plugin.Plugin;
import org.bukkit.plugin.RegisteredListener;
import org.bukkit.plugin.TimedRegisteredListener;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
public class TimingsCommand extends Command {
public TimingsCommand(String name) {
@ -22,11 +27,21 @@ public class TimingsCommand extends Command {
public boolean execute(CommandSender sender, String currentAlias, String[] args) {
if (!testPermission(sender)) return true;
if (args.length != 1) return false;
if (!sender.getServer().getPluginManager().useTimings()) {
sender.sendMessage("Please enable timings by setting \"settings.plugin-profiling\" to true in bukkit.yml");
return true;
}
boolean seperate = "seperate".equals(args[0]);
if ("reset".equals(args[0])) {
for (Plugin plugin : Bukkit.getPluginManager().getPlugins()) {
plugin.resetTimings();
for (HandlerList handlerList : HandlerList.getHandlerLists()) {
for (RegisteredListener[] listeners : handlerList.getRegisteredListeners()) {
for (RegisteredListener listener : listeners) {
if (listener instanceof TimedRegisteredListener) {
((TimedRegisteredListener)listener).reset();
}
}
}
}
sender.sendMessage("Timings reset");
} else if ("merged".equals(args[0]) || seperate) {
@ -53,11 +68,18 @@ public class TimingsCommand extends Command {
fileTimings.println("Plugin " + pluginIdx);
}
else fileTimings.println(plugin.getDescription().getFullName());
for (Event.Type type : Event.Type.values()) {
long time = plugin.getTiming(type);
totalTime += time;
if (time > 0) {
fileTimings.println(" " + type.name() + " " + time);
for (RegisteredListener listener : HandlerList.getRegisteredListeners(plugin)) {
if (listener instanceof TimedRegisteredListener) {
TimedRegisteredListener trl = (TimedRegisteredListener) listener;
long time = trl.getTotalTime();
int count = trl.getCount();
if (count == 0) continue;
long avg = time / count;
totalTime += time;
Event event = trl.getEvent();
if (count > 0 && event != null) {
fileTimings.println(" " + event.getClass().getSimpleName() + (trl.hasMultiple() ? " (and others)" : "") + " Time: " + time + " Count: " + count + " Avg: " + avg);
}
}
}
fileTimings.println(" Total time " + totalTime + " (" + totalTime / 1000000000 + "s)");

View File

@ -132,4 +132,22 @@ public class HandlerList {
public RegisteredListener[][] getRegisteredListeners() {
return handlers;
}
public static ArrayList<RegisteredListener> getRegisteredListeners(Plugin plugin) {
ArrayList<RegisteredListener> listeners = new ArrayList<RegisteredListener>();
for (HandlerList h : alllists) {
for (List<RegisteredListener> list : h.handlerslots.values()) {
for (RegisteredListener listener : list) {
if (listener.getPlugin().equals(plugin)) {
listeners.add(listener);
}
}
}
}
return listeners;
}
public static ArrayList<HandlerList> getHandlerLists() {
return (ArrayList<HandlerList>) alllists.clone();
}
}

View File

@ -158,10 +158,4 @@ public interface Plugin extends CommandExecutor {
* @return Logger associated with this server
*/
public Logger getLogger();
public long getTiming(Event.Type type);
public void incTiming(Event.Type type, long delta);
public void resetTimings();
}

View File

@ -276,4 +276,11 @@ public interface PluginManager {
* @return Set containing all current registered permissions
*/
public Set<Permission> getPermissions();
/**
* Returns whether or not timing code should be used for event calls
*
* @return True if event timings are to be used
*/
public boolean useTimings();
}

View File

@ -33,6 +33,7 @@ public final class SimplePluginManager implements PluginManager {
private final Map<Boolean, Set<Permission>> defaultPerms = new LinkedHashMap<Boolean, Set<Permission>>();
private final Map<String, Map<Permissible, Boolean>> permSubs = new HashMap<String, Map<Permissible, Boolean>>();
private final Map<Boolean, Map<Permissible, Boolean>> defSubs = new HashMap<Boolean, Map<Permissible, Boolean>>();
private boolean useTimings = false;
public SimplePluginManager(Server instance, SimpleCommandMap commandMap) {
server = instance;
@ -323,9 +324,7 @@ public final class SimplePluginManager implements PluginManager {
}
try {
long start = System.nanoTime();
registration.callEvent(event);
registration.getPlugin().incTiming(event.getType(), System.nanoTime() - start);
} catch (AuthorNagException ex) {
Plugin plugin = registration.getPlugin();
@ -393,7 +392,11 @@ public final class SimplePluginManager implements PluginManager {
throw new IllegalPluginAccessException("Plugin attempted to register " + type + " while not enabled");
}
getEventListeners(type.getEventClass()).register(new RegisteredListener(listener, plugin.getPluginLoader().createExecutor(type, listener), priority.getNewPriority(), plugin));
if (useTimings) {
getEventListeners(type.getEventClass()).register(new TimedRegisteredListener(listener, plugin.getPluginLoader().createExecutor(type, listener), priority.getNewPriority(), plugin));
} else {
getEventListeners(type.getEventClass()).register(new RegisteredListener(listener, plugin.getPluginLoader().createExecutor(type, listener), priority.getNewPriority(), plugin));
}
}
/**
@ -422,7 +425,12 @@ public final class SimplePluginManager implements PluginManager {
throw new IllegalPluginAccessException("Plugin attempted to register " + type + " while not enabled");
}
getEventListeners(type.getEventClass()).register(new RegisteredListener(listener, executor, priority.getNewPriority(), plugin));
if (useTimings) {
getEventListeners(type.getEventClass()).register(new TimedRegisteredListener(listener, executor, priority.getNewPriority(), plugin));
}
else {
getEventListeners(type.getEventClass()).register(new RegisteredListener(listener, executor, priority.getNewPriority(), plugin));
}
}
public void registerEvents(Listener listener, Plugin plugin) {
@ -445,7 +453,11 @@ public final class SimplePluginManager implements PluginManager {
throw new IllegalPluginAccessException("Plugin attempted to register " + event + " while not enabled");
}
getEventListeners(event).register(new RegisteredListener(listener, executor, priority, plugin));
if (useTimings) {
getEventListeners(event).register(new TimedRegisteredListener(listener, executor, priority, plugin));
} else {
getEventListeners(event).register(new RegisteredListener(listener, executor, priority, plugin));
}
}
/**
@ -606,4 +618,17 @@ public final class SimplePluginManager implements PluginManager {
public Set<Permission> getPermissions() {
return new HashSet<Permission>(permissions.values());
}
public boolean useTimings() {
return useTimings;
}
/**
* Sets whether or not per event timing code should be used
*
* @param use True if per event timing code should be used
*/
public void useTimings(boolean use) {
useTimings = use;
}
}

View File

@ -0,0 +1,77 @@
package org.bukkit.plugin;
import org.bukkit.event.Event;
import org.bukkit.event.EventException;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
/**
* Extends RegisteredListener to include timing information
*/
public class TimedRegisteredListener extends RegisteredListener {
private int count;
private long totalTime;
private Event event;
private boolean multiple = false;
public TimedRegisteredListener(final Listener pluginListener, final EventExecutor eventExecutor, final EventPriority eventPriority, final Plugin registeredPlugin) {
super(pluginListener, eventExecutor, eventPriority, registeredPlugin);
}
public void callEvent(Event event) throws EventException {
count++;
if (this.event == null) {
this.event = event;
}
else if (!this.event.getClass().equals(event.getClass())) {
multiple = true;
}
long start = System.nanoTime();
super.callEvent(event);
totalTime += System.nanoTime() - start;
}
/**
* Resets the call count and total time for this listener
*/
public void reset() {
count = 0;
totalTime = 0;
}
/**
* Gets the total times this listener has been called
*
* @return Times this listener has been called
*/
public int getCount() {
return count;
}
/**
* Gets the total time calls to this listener have taken
*
* @return Total time for all calls of this listener
*/
public long getTotalTime() {
return totalTime;
}
/**
* Gets the first event this listener handled
*
* @return An event handled by this RegisteredListener
*/
public Event getEvent() {
return event;
}
/**
* Gets whether this listener has handled multiple events
*
* @return True if this listener has handled multiple events
*/
public boolean hasMultiple() {
return multiple;
}
}

View File

@ -45,7 +45,6 @@ public abstract class JavaPlugin implements Plugin {
private EbeanServer ebean = null;
private FileConfiguration newConfig = null;
private File configFile = null;
private long[] timings = new long[Event.Type.values().length];
private PluginLogger logger = null;
public JavaPlugin() {}
@ -374,18 +373,6 @@ public abstract class JavaPlugin implements Plugin {
return logger;
}
public long getTiming(Event.Type type) {
return timings[type.ordinal()];
}
public void incTiming(Event.Type type, long delta) {
timings[type.ordinal()] += delta;
}
public void resetTimings() {
timings = new long[Event.Type.values().length];
}
@Override
public String toString() {
return getDescription().getFullName();

View File

@ -992,6 +992,7 @@ public class JavaPluginLoader implements PluginLoader {
}
public Map<Class<? extends Event>, Set<RegisteredListener>> createRegisteredListeners(Listener listener, final Plugin plugin) {
boolean useTimings = server.getPluginManager().useTimings();
Map<Class<? extends Event>, Set<RegisteredListener>> ret = new HashMap<Class<? extends Event>, Set<RegisteredListener>>();
Method[] methods;
try {
@ -1016,7 +1017,7 @@ public class JavaPluginLoader implements PluginLoader {
eventSet = new HashSet<RegisteredListener>();
ret.put(eventClass, eventSet);
}
eventSet.add(new RegisteredListener(listener, new EventExecutor() {
EventExecutor executor = new EventExecutor() {
public void execute(Listener listener, Event event) throws EventException {
try {
if (!eventClass.isAssignableFrom(event.getClass())) {
@ -1027,7 +1028,12 @@ public class JavaPluginLoader implements PluginLoader {
throw new EventException(t);
}
}
}, eh.priority(), plugin));
};
if (useTimings) {
eventSet.add(new TimedRegisteredListener(listener, executor, eh.priority(), plugin));
} else {
eventSet.add(new RegisteredListener(listener, executor, eh.priority(), plugin));
}
}
return ret;
}