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..07ad3210e 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; } /** @@ -69,8 +90,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; } diff --git a/docs/optimizing-with-codeflash/trace-and-optimize.mdx b/docs/optimizing-with-codeflash/trace-and-optimize.mdx index 9a3e84531..0f103cc54 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 + # Class with classpath (recommended — works with any compiled project) codeflash optimize java -cp target/classes com.example.Main # Executable JAR (requires maven-jar-plugin or equivalent with Main-Class manifest) -codeflash optimize java -jar target/my-app.jar --app-args - -# Maven exec -codeflash optimize mvn exec:java -Dexec.mainClass="com.example.Main" +codeflash optimize java -jar target/my-app.jar ``` For long-running programs (servers, benchmarks), use `--timeout` to limit each tracing stage: @@ -232,14 +231,35 @@ The Java tracer uses a **two-stage approach**: JFR (Java Flight Recorder) for ac codeflash optimize java -cp target/classes com.example.Main # Executable JAR (requires maven-jar-plugin or equivalent with Main-Class manifest) - codeflash optimize java -jar target/my-app.jar --app-args + codeflash optimize java -jar target/my-app.jar ``` The `-cp` approach works with any project after `mvn compile` or `gradle build`. The `-jar` approach requires your project to produce an executable JAR with a `Main-Class` entry in the manifest — this is not the default Maven behavior. 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: @@ -249,28 +269,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. -