From 8867e184a871422186e7d042243a94d17bdee595 Mon Sep 17 00:00:00 2001 From: Tugamer89 <61603718+Tugamer89@users.noreply.github.com> Date: Tue, 26 May 2026 05:00:50 +0000 Subject: [PATCH] perf: add fast-path accepts evaluation to bypass execution trace overhead Co-authored-by: google-labs-jules[bot] <161369871+google-labs-jules[bot]@users.noreply.github.com> --- src/main/java/org/eu/autogex/models/DFA.java | 28 +++++++++++++++++++ src/main/java/org/eu/autogex/models/ENFA.java | 25 +++++++++++++++++ src/main/java/org/eu/autogex/models/NFA.java | 24 ++++++++++++++++ 3 files changed, 77 insertions(+) diff --git a/src/main/java/org/eu/autogex/models/DFA.java b/src/main/java/org/eu/autogex/models/DFA.java index c5360541..411b55f5 100644 --- a/src/main/java/org/eu/autogex/models/DFA.java +++ b/src/main/java/org/eu/autogex/models/DFA.java @@ -18,6 +18,34 @@ private DFA(Builder builder) { this.transitionTable = Map.copyOf(builder.transitionTable); } + /** + * Fast-path evaluation of an input string bypassing ExecutionTrace generation. Overrides the + * default method to minimize memory allocation and maximize performance. + * + * @param input The string to be evaluated. + * @return true if the string is accepted, false otherwise. + */ + @Override + public boolean accepts(String input) { + State currentState = initialState; + + for (int i = 0; i < input.length(); i++) { + char symbol = input.charAt(i); + Map stateTransitions = transitionTable.get(currentState); + + if (stateTransitions == null) { + return false; + } + + currentState = stateTransitions.get(symbol); + if (currentState == null) { + return false; + } + } + + return finalStates.contains(currentState); + } + @Override public ExecutionTrace execute(String input) { List steps = new ArrayList<>(); diff --git a/src/main/java/org/eu/autogex/models/ENFA.java b/src/main/java/org/eu/autogex/models/ENFA.java index 2da75c02..3f2194c7 100644 --- a/src/main/java/org/eu/autogex/models/ENFA.java +++ b/src/main/java/org/eu/autogex/models/ENFA.java @@ -52,6 +52,31 @@ public Set epsilonClosure(Set startStates) { return closure; } + /** + * Fast-path evaluation of an input string bypassing ExecutionTrace generation. Overrides the + * default method to minimize memory allocation and maximize performance. + * + * @param input The string to be evaluated. + * @return true if the string is accepted, false otherwise. + */ + @Override + public boolean accepts(String input) { + Set currentStates = epsilonClosure(Set.of(initialState)); + + for (int i = 0; i < input.length(); i++) { + char symbol = input.charAt(i); + + Set moveResult = computeNextStates(currentStates, symbol, transitionTable); + currentStates = epsilonClosure(moveResult); + + if (currentStates.isEmpty()) { + return false; + } + } + + return !Collections.disjoint(currentStates, finalStates); + } + @Override public ExecutionTrace execute(String input) { List steps = new ArrayList<>(); diff --git a/src/main/java/org/eu/autogex/models/NFA.java b/src/main/java/org/eu/autogex/models/NFA.java index e9f17d35..f2b8ae90 100644 --- a/src/main/java/org/eu/autogex/models/NFA.java +++ b/src/main/java/org/eu/autogex/models/NFA.java @@ -18,6 +18,30 @@ private NFA(Builder builder) { this.transitionTable = Map.copyOf(builder.transitionTable); } + /** + * Fast-path evaluation of an input string bypassing ExecutionTrace generation. Overrides the + * default method to minimize memory allocation and maximize performance. + * + * @param input The string to be evaluated. + * @return true if the string is accepted, false otherwise. + */ + @Override + public boolean accepts(String input) { + Set currentStates = Set.of(initialState); + + for (int i = 0; i < input.length(); i++) { + char symbol = input.charAt(i); + + currentStates = computeNextStates(currentStates, symbol, transitionTable); + + if (currentStates.isEmpty()) { + return false; + } + } + + return !Collections.disjoint(currentStates, finalStates); + } + @Override public ExecutionTrace execute(String input) { List steps = new ArrayList<>();