From 642ce57c820086b6193098185d3645bb557b904e Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sat, 18 Apr 2026 03:08:03 +0000 Subject: [PATCH 1/3] Optimize nested perf timer overhead in hot paths Agent-Logs-Url: https://github.com/coderive-lang/Coderive/sessions/36d250ed-3343-476f-856a-509b35f09d2a Co-authored-by: DanexCodr <216312766+DanexCodr@users.noreply.github.com> --- src/main/java/cod/ast/ASTVisitor.java | 5 +- src/main/java/cod/debug/DebugSystem.java | 59 ++++++++++++++----- .../interpreter/context/ExecutionContext.java | 5 +- .../handler/ExpressionHandler.java | 5 +- src/main/java/cod/range/NaturalArray.java | 5 +- .../java/cod/semantic/ImportResolver.java | 5 +- 6 files changed, 55 insertions(+), 29 deletions(-) diff --git a/src/main/java/cod/ast/ASTVisitor.java b/src/main/java/cod/ast/ASTVisitor.java index 41ff2af..c6ade16 100644 --- a/src/main/java/cod/ast/ASTVisitor.java +++ b/src/main/java/cod/ast/ASTVisitor.java @@ -297,9 +297,8 @@ private static String startPerfTimer(DebugSystem.Level level, String operation) if (!isTimerEnabled(level)) { return null; } - String timerName = operation + "#" + Thread.currentThread().getId() + ":" + System.nanoTime(); - DebugSystem.startTimer(level, timerName); - return timerName; + DebugSystem.startTimer(level, operation); + return operation; } private static void stopPerfTimer(String timerName) { diff --git a/src/main/java/cod/debug/DebugSystem.java b/src/main/java/cod/debug/DebugSystem.java index d1bd3e8..162b269 100644 --- a/src/main/java/cod/debug/DebugSystem.java +++ b/src/main/java/cod/debug/DebugSystem.java @@ -32,9 +32,11 @@ public int getLevel() { private static SimpleDateFormat timeFormat = new SimpleDateFormat("HH:mm:ss.SSS"); private static final boolean BENCHMARK_MODE = parseBenchmarkMode(); - // Level-based timers (new) - private static Map levelTimers = new HashMap(); - private static Map timerLevels = new HashMap(); + // Level-based timers (support nested same-name timers per thread) + private static final ThreadLocal>> levelTimerStacks = + ThreadLocal.withInitial(() -> new HashMap>()); + private static final ThreadLocal>> timerLevelStacks = + ThreadLocal.withInitial(() -> new HashMap>()); private static boolean parseBenchmarkMode() { String raw = System.getProperty("cod.benchmark.mode"); @@ -112,20 +114,48 @@ public static void startTimer(String name) { // New level-based timer public static void startTimer(Level level, String name) { if (shouldLog(level)) { - levelTimers.put(name, System.nanoTime()); - timerLevels.put(name, level); + Map> startsByName = levelTimerStacks.get(); + Deque starts = startsByName.get(name); + if (starts == null) { + starts = new ArrayDeque(); + startsByName.put(name, starts); + } + starts.push(System.nanoTime()); + + Map> levelsByName = timerLevelStacks.get(); + Deque levels = levelsByName.get(name); + if (levels == null) { + levels = new ArrayDeque(); + levelsByName.put(name, levels); + } + levels.push(level); } } // Unified stopTimer - works for both original and level-based timers public static double stopTimer(String name) { - // Check level-based timers first - Long levelStart = levelTimers.remove(name); - if (levelStart != null) { - Level originalLevel = timerLevels.remove(name); + // Check level-based timers first (LIFO for nested same-name timers) + Map> startsByName = levelTimerStacks.get(); + Deque starts = startsByName.get(name); + if (starts != null && !starts.isEmpty()) { + long levelStart = starts.pop(); + if (starts.isEmpty()) { + startsByName.remove(name); + } + + Map> levelsByName = timerLevelStacks.get(); + Deque levels = levelsByName.get(name); + Level originalLevel = null; + if (levels != null && !levels.isEmpty()) { + originalLevel = levels.pop(); + if (levels.isEmpty()) { + levelsByName.remove(name); + } + } + long durationNs = System.nanoTime() - levelStart; double durationMs = durationNs / 1_000_000.0; - + if (originalLevel != null && shouldLog(originalLevel)) { log(originalLevel, "PERF", String.format("%s took %.3f ms", name, durationMs)); } @@ -148,9 +178,10 @@ public static double stopTimer(String name) { public static double getTimerDuration(String name) { // Check level-based timers first - Long levelStart = levelTimers.get(name); - if (levelStart != null) { - long durationNs = System.nanoTime() - levelStart; + Map> startsByName = levelTimerStacks.get(); + Deque starts = startsByName.get(name); + if (starts != null && !starts.isEmpty()) { + long durationNs = System.nanoTime() - starts.peek(); return durationNs / 1_000_000.0; } @@ -207,4 +238,4 @@ private static boolean shouldLog(Level level) { public static Level getLevel() { return currentLevel; } -} \ No newline at end of file +} diff --git a/src/main/java/cod/interpreter/context/ExecutionContext.java b/src/main/java/cod/interpreter/context/ExecutionContext.java index 32ef1e9..ee66cd2 100644 --- a/src/main/java/cod/interpreter/context/ExecutionContext.java +++ b/src/main/java/cod/interpreter/context/ExecutionContext.java @@ -657,9 +657,8 @@ private static String startPerfTimer(DebugSystem.Level level, String operation) if (!isTimerEnabled(level)) { return null; } - String timerName = operation + "#" + Thread.currentThread().getId() + ":" + System.nanoTime(); - DebugSystem.startTimer(level, timerName); - return timerName; + DebugSystem.startTimer(level, operation); + return operation; } private static void stopPerfTimer(String timerName) { diff --git a/src/main/java/cod/interpreter/handler/ExpressionHandler.java b/src/main/java/cod/interpreter/handler/ExpressionHandler.java index ac11971..1b78d57 100644 --- a/src/main/java/cod/interpreter/handler/ExpressionHandler.java +++ b/src/main/java/cod/interpreter/handler/ExpressionHandler.java @@ -640,9 +640,8 @@ private static String startPerfTimer(DebugSystem.Level level, String operation) if (!isTimerEnabled(level)) { return null; } - String timerName = operation + "#" + Thread.currentThread().getId() + ":" + System.nanoTime(); - DebugSystem.startTimer(level, timerName); - return timerName; + DebugSystem.startTimer(level, operation); + return operation; } private static void stopPerfTimer(String timerName) { diff --git a/src/main/java/cod/range/NaturalArray.java b/src/main/java/cod/range/NaturalArray.java index 03eb748..0eb9a6b 100644 --- a/src/main/java/cod/range/NaturalArray.java +++ b/src/main/java/cod/range/NaturalArray.java @@ -1785,9 +1785,8 @@ private static String startPerfTimer(DebugSystem.Level level, String operation) if (!isTimerEnabled(level)) { return null; } - String timerName = operation + "#" + Thread.currentThread().getId() + ":" + System.nanoTime(); - DebugSystem.startTimer(level, timerName); - return timerName; + DebugSystem.startTimer(level, operation); + return operation; } private static void stopPerfTimer(String timerName) { diff --git a/src/main/java/cod/semantic/ImportResolver.java b/src/main/java/cod/semantic/ImportResolver.java index 40c82f1..0824d4b 100644 --- a/src/main/java/cod/semantic/ImportResolver.java +++ b/src/main/java/cod/semantic/ImportResolver.java @@ -1797,9 +1797,8 @@ private static String startPerfTimer(DebugSystem.Level level, String operation) if (!isTimerEnabled(level)) { return null; } - String timerName = operation + "#" + Thread.currentThread().getId() + ":" + System.nanoTime(); - DebugSystem.startTimer(level, timerName); - return timerName; + DebugSystem.startTimer(level, operation); + return operation; } private static void stopPerfTimer(String timerName) { From 8cb1171b9bdce8f889c75410e8186ea953fba1a7 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sat, 18 Apr 2026 03:14:10 +0000 Subject: [PATCH 2/3] Reduce debug timer overhead in binary op hot path Agent-Logs-Url: https://github.com/coderive-lang/Coderive/sessions/36d250ed-3343-476f-856a-509b35f09d2a Co-authored-by: DanexCodr <216312766+DanexCodr@users.noreply.github.com> --- src/main/java/cod/interpreter/handler/ExpressionHandler.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/cod/interpreter/handler/ExpressionHandler.java b/src/main/java/cod/interpreter/handler/ExpressionHandler.java index 1b78d57..402fdd4 100644 --- a/src/main/java/cod/interpreter/handler/ExpressionHandler.java +++ b/src/main/java/cod/interpreter/handler/ExpressionHandler.java @@ -30,7 +30,7 @@ public ExpressionHandler(TypeHandler typeSystem, InterpreterVisitor dispatcher) // === Core Expression Evaluation === public Object handleBinaryOp(BinaryOp node, ExecutionContext ctx) { - String timer = startPerfTimer(DebugSystem.Level.DEBUG, "expression.handleBinaryOp"); + String timer = startPerfTimer(DebugSystem.Level.TRACE, "expression.handleBinaryOp"); try { if (node == null) { throw new InternalError("handleBinaryOp called with null node"); From 4f93dfd8995d17f2766a5935a47f6eaafafa9982 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sat, 18 Apr 2026 03:20:42 +0000 Subject: [PATCH 3/3] Finalize timer hotpath optimizations for direct and benchmark runs Agent-Logs-Url: https://github.com/coderive-lang/Coderive/sessions/36d250ed-3343-476f-856a-509b35f09d2a Co-authored-by: DanexCodr <216312766+DanexCodr@users.noreply.github.com> --- src/main/java/cod/debug/DebugSystem.java | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/src/main/java/cod/debug/DebugSystem.java b/src/main/java/cod/debug/DebugSystem.java index 162b269..185047c 100644 --- a/src/main/java/cod/debug/DebugSystem.java +++ b/src/main/java/cod/debug/DebugSystem.java @@ -34,9 +34,9 @@ public int getLevel() { // Level-based timers (support nested same-name timers per thread) private static final ThreadLocal>> levelTimerStacks = - ThreadLocal.withInitial(() -> new HashMap>()); + ThreadLocal.withInitial(HashMap::new); private static final ThreadLocal>> timerLevelStacks = - ThreadLocal.withInitial(() -> new HashMap>()); + ThreadLocal.withInitial(HashMap::new); private static boolean parseBenchmarkMode() { String raw = System.getProperty("cod.benchmark.mode"); @@ -52,6 +52,9 @@ public static boolean isBenchmarkMode() { public static void setLevel(Level level) { currentLevel = level; + if (level == Level.OFF) { + clearTimerStateForCurrentThread(); + } } public static void setShowTimestamp(boolean show) { @@ -115,19 +118,11 @@ public static void startTimer(String name) { public static void startTimer(Level level, String name) { if (shouldLog(level)) { Map> startsByName = levelTimerStacks.get(); - Deque starts = startsByName.get(name); - if (starts == null) { - starts = new ArrayDeque(); - startsByName.put(name, starts); - } + Deque starts = startsByName.computeIfAbsent(name, k -> new ArrayDeque<>()); starts.push(System.nanoTime()); Map> levelsByName = timerLevelStacks.get(); - Deque levels = levelsByName.get(name); - if (levels == null) { - levels = new ArrayDeque(); - levelsByName.put(name, levels); - } + Deque levels = levelsByName.computeIfAbsent(name, k -> new ArrayDeque<>()); levels.push(level); } } @@ -238,4 +233,9 @@ private static boolean shouldLog(Level level) { public static Level getLevel() { return currentLevel; } + + public static void clearTimerStateForCurrentThread() { + levelTimerStacks.remove(); + timerLevelStacks.remove(); + } }