diff --git a/common/src/main/java/com/dfsek/terra/profiler/ProfilerImpl.java b/common/src/main/java/com/dfsek/terra/profiler/ProfilerImpl.java index b84986e3d..5e4998010 100644 --- a/common/src/main/java/com/dfsek/terra/profiler/ProfilerImpl.java +++ b/common/src/main/java/com/dfsek/terra/profiler/ProfilerImpl.java @@ -10,8 +10,8 @@ import java.util.Stack; public class ProfilerImpl implements Profiler { private static final ThreadLocal> THREAD_STACK = ThreadLocal.withInitial(Stack::new); - private static final ThreadLocal> TIMINGS = ThreadLocal.withInitial(HashMap::new); - private final List> accessibleThreadMaps = new ArrayList<>(); + private static final ThreadLocal>> TIMINGS = ThreadLocal.withInitial(HashMap::new); + private final List>> accessibleThreadMaps = new ArrayList<>(); private volatile boolean running = false; @@ -21,7 +21,10 @@ public class ProfilerImpl implements Profiler { @Override public void push(String frame) { - if(running) THREAD_STACK.get().push(new Frame(frame)); + if(running) { + Stack stack = THREAD_STACK.get(); + stack.push(new Frame(stack.size() == 0 ? frame : stack.peek().getId() + "." + frame)); + } } @Override @@ -30,7 +33,7 @@ public class ProfilerImpl implements Profiler { long time = System.nanoTime(); Stack stack = THREAD_STACK.get(); - Map timingsMap = TIMINGS.get(); + Map> timingsMap = TIMINGS.get(); if(timingsMap.size() == 0) { synchronized(accessibleThreadMaps) { @@ -38,16 +41,13 @@ public class ProfilerImpl implements Profiler { } } - Timings bottom = timingsMap.computeIfAbsent(stack.get(0).getId(), id -> new Timings()); - - for(int i = 1; i < stack.size(); i++) { - bottom = bottom.getSubItem(stack.get(i).getId()); - } - Frame top = stack.pop(); - if(!top.getId().equals(frame)) throw new MalformedStackException("Expected " + frame + ", found " + top); + if((stack.size() != 0 && !top.getId().endsWith("." + frame)) || (stack.size() == 0 && !top.getId().equals(frame))) + throw new MalformedStackException("Expected " + frame + ", found " + top); - bottom.addTime(time - top.getStart()); + List timings = timingsMap.computeIfAbsent(top.getId(), id -> new ArrayList<>()); + + timings.add(time - top.getStart()); } } @@ -64,7 +64,16 @@ public class ProfilerImpl implements Profiler { @Override public Map getTimings() { Map map = new HashMap<>(); - accessibleThreadMaps.forEach(map::putAll); + accessibleThreadMaps.forEach(smap -> { + smap.forEach((key, list) -> { + String[] keys = key.split("\\."); + Timings timings = map.computeIfAbsent(keys[0], id -> new Timings()); + for(int i = 1; i < keys.length; i++) { + timings = timings.getSubItem(keys[i]); + } + list.forEach(timings::addTime); + }); + }); return map; } } diff --git a/common/src/test/java/profiler/ProfilerTest.java b/common/src/test/java/profiler/ProfilerTest.java index 1660310f8..813e08eae 100644 --- a/common/src/test/java/profiler/ProfilerTest.java +++ b/common/src/test/java/profiler/ProfilerTest.java @@ -6,7 +6,7 @@ public class ProfilerTest { //@Test public static void main(String... a) throws InterruptedException { Profiler.INSTANCE.start(); - for(int i = 0; i < 100; i++) { + for(int i = 0; i < 1000; i++) { doThing(); }