From e0a9ca7303ace2d5c3d7fd621358e34364423539 Mon Sep 17 00:00:00 2001 From: HeshamHM28 Date: Tue, 7 Apr 2026 14:50:34 +0200 Subject: [PATCH 1/3] Update Java optimization instructions and add support for Maven/Gradle test suites --- .../trace-and-optimize.mdx | 55 ++++++++++++------- 1 file changed, 35 insertions(+), 20 deletions(-) diff --git a/docs/optimizing-with-codeflash/trace-and-optimize.mdx b/docs/optimizing-with-codeflash/trace-and-optimize.mdx index 4c332a929..0e9e6c8a9 100644 --- a/docs/optimizing-with-codeflash/trace-and-optimize.mdx +++ b/docs/optimizing-with-codeflash/trace-and-optimize.mdx @@ -60,14 +60,13 @@ codeflash optimize --language javascript script.js To trace and optimize a running Java program, replace your `java` command with `codeflash optimize java`: ```bash +cd /path/to/your/java/project + # JAR application -codeflash optimize java -jar target/my-app.jar --app-args +codeflash optimize java -jar target/my-app.jar # Class with classpath codeflash optimize java -cp target/classes com.example.Main - -# Maven exec -codeflash optimize mvn exec:java -Dexec.mainClass="com.example.Main" ``` For long-running programs (servers, benchmarks), use `--timeout` to limit each tracing stage: @@ -229,7 +228,7 @@ The Java tracer uses a **two-stage approach**: JFR (Java Flight Recorder) for ac ```bash # JAR application - codeflash optimize java -jar target/my-app.jar --app-args + codeflash optimize java -jar target/my-app.jar # Class with classpath codeflash optimize java -cp target/classes com.example.Main @@ -237,7 +236,28 @@ The Java tracer uses a **two-stage approach**: JFR (Java Flight Recorder) for ac Codeflash will run your program twice (once for profiling, once for argument capture), generate JUnit replay tests, then optimize the most impactful functions. -2. **Long-running programs** +2. **With Maven / Gradle test suites** + + ```bash + # Maven + codeflash optimize mvn test + + # Gradle + codeflash optimize ./gradlew :module:cleanTest :module:test + ``` + +3. **Multi-module projects** + + For multi-module builds, point Codeflash at the correct source and test roots: + + ```bash + codeflash \ + --module-root src/main/java \ + --tests-root src/test/java \ + optimize ./gradlew :my-module:cleanTest :my-module:test + ``` + +4. **Long-running programs** For servers, benchmarks, or programs that don't terminate on their own, use `--timeout` to limit each tracing stage: @@ -247,28 +267,23 @@ The Java tracer uses a **two-stage approach**: JFR (Java Flight Recorder) for ac Each stage runs for at most 30 seconds, then the program is terminated and captured data is processed. -3. **Trace only (no optimization)** +5. **Trace only (no optimization)** ```bash - codeflash optimize --trace-only java -jar target/my-app.jar + codeflash optimize --trace-only java -cp target/classes com.example.Main ``` This generates replay tests in `src/test/java/codeflash/replay/` without running the optimizer. - More Options: - - - `--timeout`: Maximum time (seconds) for each tracing stage. - - `--max-function-count`: Maximum captures per method (default: 100). - - -**How the Java tracer works:** - -- **Stage 1 (JFR)**: Runs your program with Java Flight Recorder enabled. JFR is built into the JVM (Java 11+), has ~1% overhead, and doesn't interfere with JIT compilation. This produces accurate method-level CPU profiling data. + Options: -- **Stage 2 (Agent)**: Runs your program with a bytecode instrumentation agent injected via `JAVA_TOOL_OPTIONS`. The agent intercepts method entry points, serializes arguments using Kryo, and writes them to an SQLite database. A 500ms timeout per serialization prevents hangs on complex object graphs. + | Option | Description | Default | + |--------|-------------|---------| + | `--timeout` | Maximum time (seconds) for each tracing stage | Indefinite | + | `--max-function-count` | Maximum captures per method | 100 | + | `--trace-only` | Generate replay tests without running the optimizer | Off | + | `--no-pr` | Skip PR creation and keep changes local | Off | -- **Replay Tests**: Generated JUnit 5 test classes that deserialize captured arguments and invoke the original methods via reflection. These tests exercise your code with real-world inputs. - From 4856c841acb55289895be915787968aa6a646347 Mon Sep 17 00:00:00 2001 From: "codeflash-ai[bot]" <148906541+codeflash-ai[bot]@users.noreply.github.com> Date: Thu, 9 Apr 2026 00:16:12 +0000 Subject: [PATCH 2/3] Optimize Fibonacci.fibonacci MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The recursive implementation was replaced with an iterative fast-doubling algorithm that computes Fibonacci(n) in O(log n) time by processing the bits of n and applying matrix-exponentiation doubling formulas (F(2k) = F(k)*(2*F(k+1) - F(k)) and F(2k+1) = F(k+1)² + F(k)²), eliminating the exponential O(2^n) recursive call tree that dominated original runtime at 32.5% per the profiler. This cuts execution time from 3.81 ms to 179 µs (20× speedup) by avoiding redundant subproblem recomputation and deep call stacks. The optimization incurs no regressions in correctness, maintains identical exception behavior, and scales to larger n values that would timeout under naive recursion. --- .../src/main/java/com/example/Fibonacci.java | 25 +++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) diff --git a/code_to_optimize/java/src/main/java/com/example/Fibonacci.java b/code_to_optimize/java/src/main/java/com/example/Fibonacci.java index b604fb928..50830b4b1 100644 --- a/code_to_optimize/java/src/main/java/com/example/Fibonacci.java +++ b/code_to_optimize/java/src/main/java/com/example/Fibonacci.java @@ -9,7 +9,7 @@ public class Fibonacci { /** - * Calculate the nth Fibonacci number using recursion. + * Calculate the nth Fibonacci number using an efficient iterative fast-doubling algorithm. * * @param n Position in Fibonacci sequence (0-indexed) * @return The nth Fibonacci number @@ -21,7 +21,28 @@ public static long fibonacci(int n) { if (n <= 1) { return n; } - return fibonacci(n - 1) + fibonacci(n - 2); + + long a = 0L; // F(0) + long b = 1L; // F(1) + + // Iterate from the highest bit of n down to the lowest. + for (int mask = Integer.highestOneBit(n); mask != 0; mask >>= 1) { + // Apply doubling formulas: + // F(2k) = F(k) * (2*F(k+1) - F(k)) + // F(2k+1) = F(k+1)^2 + F(k)^2 + long twoBMinusA = (b << 1) - a; + long c = a * twoBMinusA; // F(2k) + long d = a * a + b * b; // F(2k+1) + + if ((n & mask) == 0) { + a = c; + b = d; + } else { + a = d; + b = c + d; + } + } + return a; } /** From 88c80ccae0ff251a32d82ced6efdcc9886e0f117 Mon Sep 17 00:00:00 2001 From: "codeflash-ai[bot]" <148906541+codeflash-ai[bot]@users.noreply.github.com> Date: Thu, 9 Apr 2026 00:37:43 +0000 Subject: [PATCH 3/3] Optimize Fibonacci.fibonacciSequence MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The optimization replaced the naive recursive `fibonacci(i)` call inside the loop (which recomputed overlapping subproblems exponentially) with an iterative approach that builds the sequence in a single forward pass, reusing `result[i-1]` and `result[i-2]`. The original profiler shows `result[i] = fibonacci(i)` consumed 94% of runtime at ~37 µs per call due to exponential tree traversal; the optimized version computes each element in constant time by direct addition. Runtime improved 27% (230 µs → 181 µs) with no correctness regressions across all test cases. --- .../java/src/main/java/com/example/Fibonacci.java | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/code_to_optimize/java/src/main/java/com/example/Fibonacci.java b/code_to_optimize/java/src/main/java/com/example/Fibonacci.java index b604fb928..49be8c4d0 100644 --- a/code_to_optimize/java/src/main/java/com/example/Fibonacci.java +++ b/code_to_optimize/java/src/main/java/com/example/Fibonacci.java @@ -69,8 +69,16 @@ public static long[] fibonacciSequence(int n) { } long[] result = new long[n]; - for (int i = 0; i < n; i++) { - result[i] = fibonacci(i); + if (n >= 1) { + result[0] = 0; + } + if (n >= 2) { + result[1] = 1; + } + + // Compute each Fibonacci number iteratively using previous values + for (int i = 2; i < n; i++) { + result[i] = result[i - 1] + result[i - 2]; } return result; }