Skip to content

Commit e9bfb3d

Browse files
committed
Timings reporter, hooks and fixes.
1 parent 25baff9 commit e9bfb3d

File tree

5 files changed

+191
-5
lines changed

5 files changed

+191
-5
lines changed

src/main/java/ch/njol/skript/lang/TriggerItem.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@
2727
import org.eclipse.jdt.annotation.Nullable;
2828

2929
import ch.njol.skript.Skript;
30+
import ch.njol.skript.timings.Timing;
31+
import ch.njol.skript.timings.Timings;
3032
import ch.njol.util.StringUtils;
3133

3234
/**
@@ -86,9 +88,14 @@ protected TriggerItem walk(final Event e) {
8688
public final static boolean walk(final TriggerItem start, final Event e) {
8789
assert start != null && e != null;
8890
TriggerItem i = start;
91+
Timing timing = null;
8992
try {
93+
if (Timings.enabled())
94+
timing = Timings.start(e);
95+
9096
while (i != null)
9197
i = i.walk(e);
98+
9299
return true;
93100
} catch (final StackOverflowError err) {
94101
final Trigger t = start.getTrigger();
@@ -99,6 +106,9 @@ public final static boolean walk(final TriggerItem start, final Event e) {
99106
} catch (final Exception ex) {
100107
if (ex.getStackTrace().length != 0) // empty exceptions have already been printed
101108
Skript.exception(ex, i);
109+
} finally {
110+
assert timing != null;
111+
timing.stop(); // Whatever happened, end the timing
102112
}
103113
return false;
104114
}

src/main/java/ch/njol/skript/timings/Timing.java

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,9 @@
3131

3232
import com.google.common.collect.Lists;
3333

34+
/**
35+
* Timing for certain action.
36+
*/
3437
public class Timing {
3538

3639
public class Capture {
@@ -89,8 +92,13 @@ protected Timing() {
8992
inProgress = new HashMap<Thread,Capture>();
9093
}
9194

95+
/**
96+
* Starts timing measurement for caller thread.
97+
* @return Timing for chaining
98+
*/
9299
public Timing start() {
93100
Thread current = Thread.currentThread();
101+
assert current != null;
94102
if (inProgress.containsKey(current)) {
95103
inProgress.get(current).stop();
96104
inProgress.remove(current);
@@ -103,4 +111,58 @@ public Timing start() {
103111

104112
return this;
105113
}
114+
115+
/**
116+
* Stops timing measurements for caller thread if it was in progress.
117+
*/
118+
public void stop() {
119+
Thread current = Thread.currentThread();
120+
assert current != null;
121+
if (inProgress.containsKey(current)) {
122+
inProgress.get(current).stop();
123+
inProgress.remove(current);
124+
}
125+
}
126+
127+
/**
128+
* Pauses timing measurement for caller thread until {@link #unpause()} is called.
129+
* @return Timing for chaining.
130+
*/
131+
public Timing pause() {
132+
Thread current = Thread.currentThread();
133+
assert current != null;
134+
if (inProgress.containsKey(current)) {
135+
inProgress.get(current).pause();
136+
}
137+
138+
return this;
139+
}
140+
141+
/**
142+
* Unpauses timing measurement for caller thread if it was paused.
143+
* @return Timing for chaining.
144+
*/
145+
public Timing unpause() {
146+
Thread current = Thread.currentThread();
147+
assert current != null;
148+
if (inProgress.containsKey(current)) {
149+
inProgress.get(current).unpause();
150+
}
151+
152+
return this;
153+
}
154+
155+
/**
156+
* Gets list of captures for given thread. Very expensive to call.
157+
* @param thread
158+
* @return Captures for given thread
159+
*/
160+
public List<Capture> getCaptures(Thread thread) {
161+
List<Capture> ret = new ArrayList<Capture>();
162+
for (Capture c : captures)
163+
if (c.isOf(thread))
164+
ret.add(c);
165+
166+
return ret;
167+
}
106168
}
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
/*
2+
* This file is part of Skript.
3+
*
4+
* Skript is free software: you can redistribute it and/or modify
5+
* it under the terms of the GNU General Public License as published by
6+
* the Free Software Foundation, either version 3 of the License, or
7+
* (at your option) any later version.
8+
*
9+
* Skript is distributed in the hope that it will be useful,
10+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
11+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12+
* GNU General Public License for more details.
13+
*
14+
* You should have received a copy of the GNU General Public License
15+
* along with Skript. If not, see <http://www.gnu.org/licenses/>.
16+
*
17+
*
18+
* Copyright 2011-2016 Peter Güttinger and contributors
19+
*
20+
*/
21+
22+
package ch.njol.skript.timings;
23+
24+
import java.util.HashMap;
25+
import java.util.Iterator;
26+
import java.util.List;
27+
import java.util.Map;
28+
import java.util.Map.Entry;
29+
30+
import ch.njol.skript.localization.Language;
31+
import ch.njol.skript.timings.Timing.Capture;
32+
33+
/**
34+
* Creates timing reports.
35+
*/
36+
public class TimingReporter {
37+
38+
public static String generateReport() {
39+
Map<Object,Timing> timings = Timings.timings;
40+
StringBuilder sb = new StringBuilder();
41+
42+
sb.append(String.format(Language.get("timings.start"), ((Timings.disableTime - Timings.enableTime)) / 1000000000));
43+
Map<String,Long> results = parseTimings();
44+
Iterator<Entry<String, Long>> it = results.entrySet().iterator();
45+
while (it.hasNext()) {
46+
Entry<String, Long> entry = it.next();
47+
long time = entry.getValue();
48+
sb.append(entry.getKey() + ": " + time + " (" + (time / 1000000000) + "ms)");
49+
}
50+
51+
return sb.toString();
52+
}
53+
54+
@SuppressWarnings("null")
55+
public static Map<String,Long> parseTimings() {
56+
Map<String,Long> ret = new HashMap<String,Long>();
57+
58+
Iterator<Entry<Object, Timing>> it = Timings.timings.entrySet().iterator();
59+
while (it.hasNext()) {
60+
Entry<Object, Timing> entry = it.next();
61+
List<Capture> captures = entry.getValue().getCaptures(Thread.currentThread());
62+
long time = 0;
63+
for (Capture c : captures)
64+
time += c.result();
65+
ret.put(entry.toString(), time);
66+
}
67+
68+
return ret;
69+
}
70+
}

src/main/java/ch/njol/skript/timings/Timings.java

Lines changed: 45 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -31,20 +31,60 @@
3131
*/
3232
public class Timings {
3333

34-
private static Map<String,Timing> timings = new HashMap<String,Timing>();
34+
protected static Map<Object,Timing> timings = new HashMap<Object,Timing>();
35+
private static volatile boolean enabled;
36+
protected static volatile long enableTime;
37+
protected static volatile long disableTime;
3538

36-
public static Timing of(String name) {
39+
public static Timing of(Object ref) {
3740
Timing timing;
3841
synchronized (timings) {
39-
if (timings.containsKey(name)) {
40-
timing = timings.get(name);
42+
if (timings.containsKey(ref)) {
43+
timing = timings.get(ref);
4144
} else {
4245
timing = new Timing();
43-
timings.put(name, timing);
46+
timings.put(ref, timing);
4447
}
4548
}
4649

4750
assert timing != null;
4851
return timing;
4952
}
53+
54+
public static boolean enabled() {
55+
return enabled;
56+
}
57+
58+
public static void enable() {
59+
enabled = true;
60+
enableTime = System.nanoTime();
61+
}
62+
63+
public static void disable() {
64+
enabled = false;
65+
disableTime = System.nanoTime();
66+
}
67+
68+
public static Timing start(Object ref) {
69+
Timing timing = of(ref);
70+
timing.start();
71+
return timing;
72+
}
73+
74+
public static void stop(Object ref) {
75+
Timing timing = of(ref);
76+
timing.stop();
77+
}
78+
79+
public static Timing pause(Object ref) {
80+
Timing timing = of(ref);
81+
timing.pause();
82+
return timing;
83+
}
84+
85+
public static Timing unpause(Object ref) {
86+
Timing timing = of(ref);
87+
timing.unpause();
88+
return timing;
89+
}
5090
}

src/main/resources/lang/english.lang

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1027,4 +1027,8 @@ types:
10271027
io exceptions:
10281028
unknownhostexception: Cannot connect to %s
10291029
accessdeniedexception: Access denied for %s
1030+
# -- Timings Reports --
1031+
timings:
1032+
start: "Skript timings for %s seconds:"
1033+
10301034

0 commit comments

Comments
 (0)