Skip to content

Commit 490b8b7

Browse files
committed
Track compile and execution times in BexMetrics and integrate meaningful node checks in BexCompiler
1 parent c01308e commit 490b8b7

3 files changed

Lines changed: 39 additions & 7 deletions

File tree

src/main/java/blue/bex/api/BexEngine.java

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,8 @@ public BexCompiledProgram compile(BexProgramSource source) {
4343
}
4444

4545
private BexCompiledProgram compile(BexProgramSource source, BexMetrics metrics) {
46+
long start = System.nanoTime();
47+
try {
4648
BexCompiledProgramKey key = key(source);
4749
BexCompiledProgram cached = cache.get(key);
4850
if (cached != null) {
@@ -53,6 +55,9 @@ private BexCompiledProgram compile(BexProgramSource source, BexMetrics metrics)
5355
BexCompiledProgram program = new BexCompiler(metrics).compile(source);
5456
cache.put(key, program);
5557
return program;
58+
} finally {
59+
metrics.addCompileNanos(System.nanoTime() - start);
60+
}
5661
}
5762

5863
public BexExecutionResult execute(BexCompiledProgram program, BexExecutionContext context) {
@@ -63,8 +68,15 @@ public BexExecutionResult execute(BexCompiledProgram program, BexExecutionContex
6368
}
6469

6570
private BexExecutionResult execute(BexCompiledProgram program, BexExecutionContext context, BexMetrics metrics) {
71+
long start = System.nanoTime();
6672
BexRuntime runtime = new BexRuntime(program, context, gasSchedule, metrics, pointerCache);
67-
return runtime.execute();
73+
BexExecutionResult result = runtime.execute();
74+
metrics.addExecuteNanos(System.nanoTime() - start);
75+
return new BexExecutionResult(result.value(),
76+
result.changeset(),
77+
result.events(),
78+
result.gasUsed(),
79+
metrics);
6880
}
6981

7082
public BexExecutionResult compileAndExecute(BexProgramSource source, BexExecutionContext context) {

src/main/java/blue/bex/compile/BexCompiler.java

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,8 @@ public BexCompiledProgram compile(blue.bex.api.BexProgramSource source) {
4949
compiledFunctions.put(name, compileFunction(name, functionNodes.get(name)));
5050
}
5151

52-
String entryName = source.entry().orElse(text(prop(step, "entry")));
52+
FrozenNode stepExpr = meaningful(prop(step, "expr"));
53+
String entryName = source.entry().orElse(text(meaningful(prop(step, "entry"))));
5354
BexCompiledProgram.CompiledFunction root;
5455
int rootFrameSize = 0;
5556
if (entryName != null && !entryName.isEmpty()) {
@@ -62,14 +63,14 @@ public BexCompiledProgram compile(blue.bex.api.BexProgramSource source) {
6263
new ReturnStatement(sourceExpr("$root", "/entry/$call", "$call",
6364
new CallExpr(entryName, new String[0], new CompiledExpression[0]))))),
6465
null, 0);
65-
} else if (prop(step, "expr") != null) {
66+
} else if (stepExpr != null) {
6667
currentFunction = "$root";
6768
root = new BexCompiledProgram.CompiledFunction("$root", Collections.<String>emptyList(),
68-
Collections.<CompiledStatement>emptyList(), compileExpr(prop(step, "expr"), new CompileScope(), "/expr"), 0);
69+
Collections.<CompiledStatement>emptyList(), compileExpr(stepExpr, new CompileScope(), "/expr"), 0);
6970
} else {
7071
CompileScope scope = new CompileScope();
7172
currentFunction = "$root";
72-
List<CompiledStatement> statements = compileStatements(prop(step, "do"), scope, "/do");
73+
List<CompiledStatement> statements = compileStatements(meaningful(prop(step, "do")), scope, "/do");
7374
rootFrameSize = scope.frameSize();
7475
root = new BexCompiledProgram.CompiledFunction("$root", Collections.<String>emptyList(), statements, null, rootFrameSize);
7576
}
@@ -90,9 +91,10 @@ private BexCompiledProgram.CompiledFunction compileFunction(String name, FrozenN
9091
scope.declareOrGetSlot(arg);
9192
}
9293
}
93-
CompiledExpression expression = prop(functionNode, "expr") != null ? compileExpr(prop(functionNode, "expr"), scope, "/functions/" + escape(name) + "/expr") : null;
94+
FrozenNode functionExpr = meaningful(prop(functionNode, "expr"));
95+
CompiledExpression expression = functionExpr != null ? compileExpr(functionExpr, scope, "/functions/" + escape(name) + "/expr") : null;
9496
List<CompiledStatement> statements = expression == null
95-
? compileStatements(prop(functionNode, "do"), scope, "/functions/" + escape(name) + "/do")
97+
? compileStatements(meaningful(prop(functionNode, "do")), scope, "/functions/" + escape(name) + "/do")
9698
: Collections.<CompiledStatement>emptyList();
9799
currentFunction = previousFunction;
98100
return new BexCompiledProgram.CompiledFunction(name, Collections.unmodifiableList(args),
@@ -467,6 +469,16 @@ private FrozenNode prop(FrozenNode node, String key) {
467469
return null;
468470
}
469471

472+
private FrozenNode meaningful(FrozenNode node) {
473+
if (node == null) {
474+
return null;
475+
}
476+
boolean hasPayload = node.getValue() != null
477+
|| (node.getItems() != null && !node.getItems().isEmpty())
478+
|| (node.getProperties() != null && !node.getProperties().isEmpty());
479+
return hasPayload ? node : null;
480+
}
481+
470482
private FrozenNode required(FrozenNode node, String label) {
471483
if (node == null) {
472484
throw new BexException("Missing required field: " + label);

src/main/java/blue/bex/result/BexMetrics.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,8 @@ public final class BexMetrics {
4141
private long sizeEstimateCacheMisses;
4242
private long frozenWriterNodeFallbacks;
4343
private long frozenWriterChildNodeRoundTrips;
44+
private long compileNanos;
45+
private long executeNanos;
4446

4547
public BexMetrics copy() {
4648
BexMetrics copy = new BexMetrics();
@@ -77,6 +79,8 @@ public BexMetrics copy() {
7779
copy.sizeEstimateCacheMisses = sizeEstimateCacheMisses;
7880
copy.frozenWriterNodeFallbacks = frozenWriterNodeFallbacks;
7981
copy.frozenWriterChildNodeRoundTrips = frozenWriterChildNodeRoundTrips;
82+
copy.compileNanos = compileNanos;
83+
copy.executeNanos = executeNanos;
8084
return copy;
8185
}
8286

@@ -113,6 +117,8 @@ public BexMetrics copy() {
113117
public void incrementSizeEstimateCacheMisses() { sizeEstimateCacheMisses++; }
114118
public void incrementFrozenWriterNodeFallbacks() { frozenWriterNodeFallbacks++; }
115119
public void incrementFrozenWriterChildNodeRoundTrips() { frozenWriterChildNodeRoundTrips++; }
120+
public void addCompileNanos(long nanos) { compileNanos += Math.max(0L, nanos); }
121+
public void addExecuteNanos(long nanos) { executeNanos += Math.max(0L, nanos); }
116122

117123
public long compiledExecutions() { return compiledExecutions; }
118124
public long compileCacheHits() { return compileCacheHits; }
@@ -147,4 +153,6 @@ public BexMetrics copy() {
147153
public long sizeEstimateCacheMisses() { return sizeEstimateCacheMisses; }
148154
public long frozenWriterNodeFallbacks() { return frozenWriterNodeFallbacks; }
149155
public long frozenWriterChildNodeRoundTrips() { return frozenWriterChildNodeRoundTrips; }
156+
public long compileNanos() { return compileNanos; }
157+
public long executeNanos() { return executeNanos; }
150158
}

0 commit comments

Comments
 (0)