@@ -51,6 +51,8 @@ public class CompiletimeFunctionRunner {
5151 private final ImTranslator translator ;
5252 private boolean injectObjects ;
5353 private final Deque <Runnable > delayedActions = new ArrayDeque <>();
54+ private final Map <String , Long > compiletimeFunctionNanos = new LinkedHashMap <>();
55+ private long compiletimeExprNanos = 0L ;
5456
5557 public ILInterpreter getInterpreter () {
5658 return interpreter ;
@@ -97,21 +99,29 @@ public CompiletimeFunctionRunner(
9799
98100 public void run () {
99101 try {
102+ long t0 = System .nanoTime ();
100103 List <Either <ImCompiletimeExpr , ImFunction >> toExecute = new ArrayList <>();
101104 collectCompiletimeExpressions (toExecute );
102105 collectCompiletimeFunctions (toExecute );
106+ long tCollected = System .nanoTime ();
103107
104108 toExecute .sort (Comparator .comparing (this ::getOrderIndex ));
109+ long tSorted = System .nanoTime ();
105110
106111 execute (toExecute );
112+ long tExecuted = System .nanoTime ();
107113
108114
109115 if (functionFlag == FunctionFlagToRun .CompiletimeFunctions ) {
110116 interpreter .writebackGlobalState (isInjectObjects ());
111117 }
118+ long tWriteback = System .nanoTime ();
112119 runDelayedActions ();
120+ long tDelayed = System .nanoTime ();
113121
114122 partitionCompiletimeStateInitFunction ();
123+ long tPartitioned = System .nanoTime ();
124+ logCompiletimeTiming (toExecute , t0 , tCollected , tSorted , tExecuted , tWriteback , tDelayed , tPartitioned );
115125
116126 } catch (InterpreterException e ) {
117127 Element origin = e .getTrace ();
@@ -136,6 +146,48 @@ public void run() {
136146
137147 }
138148
149+ private void logCompiletimeTiming (List <Either <ImCompiletimeExpr , ImFunction >> toExecute ,
150+ long t0 , long tCollected , long tSorted , long tExecuted ,
151+ long tWriteback , long tDelayed , long tPartitioned ) {
152+ int exprCount = 0 ;
153+ int funcCount = 0 ;
154+ for (Either <ImCompiletimeExpr , ImFunction > e : toExecute ) {
155+ if (e .isLeft ()) {
156+ exprCount ++;
157+ } else {
158+ funcCount ++;
159+ }
160+ }
161+ WLogger .info (String .format (
162+ "Compiletime breakdown: total=%dms collect=%dms sort=%dms execute=%dms writeback=%dms delayed=%dms partition=%dms funcs=%d exprs=%d exprEval=%dms" ,
163+ ms (tPartitioned - t0 ),
164+ ms (tCollected - t0 ),
165+ ms (tSorted - tCollected ),
166+ ms (tExecuted - tSorted ),
167+ ms (tWriteback - tExecuted ),
168+ ms (tDelayed - tWriteback ),
169+ ms (tPartitioned - tDelayed ),
170+ funcCount ,
171+ exprCount ,
172+ ms (compiletimeExprNanos )
173+ ));
174+ if (!compiletimeFunctionNanos .isEmpty ()) {
175+ List <Map .Entry <String , Long >> top = compiletimeFunctionNanos .entrySet ().stream ()
176+ .sorted ((a , b ) -> Long .compare (b .getValue (), a .getValue ()))
177+ .limit (10 )
178+ .collect (Collectors .toList ());
179+ StringBuilder sb = new StringBuilder ("Top compiletime functions:" );
180+ for (Map .Entry <String , Long > e : top ) {
181+ sb .append ("\n " ).append (e .getKey ()).append (": " ).append (ms (e .getValue ())).append ("ms" );
182+ }
183+ WLogger .info (sb .toString ());
184+ }
185+ }
186+
187+ private static long ms (long nanos ) {
188+ return nanos / 1_000_000L ;
189+ }
190+
139191 private void partitionCompiletimeStateInitFunction () {
140192 if (compiletimeStateInitFunction == null ) {
141193 return ;
@@ -220,6 +272,7 @@ public void visit(ImCompiletimeExpr e) {
220272
221273
222274 private void executeCompiletimeExpr (ImCompiletimeExpr cte ) {
275+ long t0 = System .nanoTime ();
223276 try {
224277 ProgramState globalState = interpreter .getGlobalState ();
225278 globalState .setLastStatement (cte );
@@ -261,6 +314,8 @@ private void executeCompiletimeExpr(ImCompiletimeExpr cte) {
261314 e .setStacktrace (msg );
262315 e .setTrace (cte .attrTrace ());
263316 throw e ;
317+ } finally {
318+ compiletimeExprNanos += System .nanoTime () - t0 ;
264319 }
265320 }
266321
@@ -491,11 +546,12 @@ private ImFunction findNative(String funcName, WPos trace) {
491546
492547 private void executeCompiletimeFunction (ImFunction f ) {
493548 if (functionFlag .matches (f )) {
549+ long t0 = System .nanoTime ();
494550 try {
495551 if (!f .getBody ().isEmpty ()) {
496552 interpreter .getGlobalState ().setLastStatement (f .getBody ().get (0 ));
497553 }
498- WLogger .debug ( "running " + functionFlag + " function " + f .getName ());
554+ WLogger .trace (() -> "running " + functionFlag + " function " + f .getName ());
499555 interpreter .runVoidFunc (f , null );
500556 successTests .add (f );
501557 } catch (TestSuccessException e ) {
@@ -505,6 +561,8 @@ private void executeCompiletimeFunction(ImFunction f) {
505561 } catch (Throwable e ) {
506562 failTests .put (f , Pair .create (interpreter .getLastStatement (), e .toString ()));
507563 throw e ;
564+ } finally {
565+ compiletimeFunctionNanos .merge (f .getName (), System .nanoTime () - t0 , Long ::sum );
508566 }
509567 }
510568 }
0 commit comments