⚡️ Speed up function get_optimized_code_for_module by 14% in PR #1717 (prepare-java-support-2)#1722
Conversation
…tion
Two more instrumentation bugs:
1. Class renaming only updated the `class` declaration line, leaving
return types, constructors, and other self-references unchanged.
When the class has a method like `public OriginalClass of(...)
{ return this; }`, the renamed `this` no longer matches the
unrenamed return type. Fixed by replacing ALL word-boundary-
matched occurrences of the original class name throughout the
entire source, not just in the class declaration.
2. Captured result variables (`var _cf_result8_2 = ...`) were
declared inside nested blocks (while/for/try) but the
serialization line referencing them was placed at the end of
the method body, outside the block scope. Java block scoping
makes the variable invisible there. Fixed by serializing
immediately after each capture, while the variable is still
in scope.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The lambda detection regex only matched no-arg lambdas `() -> {`
but missed parameterized lambdas like `(a, b, c) -> {`. This caused
instrumentation to insert `_cf_serializedResult` assignments inside
lambda bodies, violating Java's effectively-final requirement for
captured variables.
Broadened the block lambda detection from `\(\s*\)\s*->\s*\{` to
`->\s*\{`, and the expression lambda detection from `\(\s*\)\s*->`
to `->\s+\S`. This correctly detects all lambda forms and skips
instrumenting calls inside them.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…eout-and-test-categorization fix: Java line profiler timeout and test categorization
The 120-second Maven timeout was only applied when test_framework == "junit5", leaving junit4 and testng with the default 15-second Python pytest timeout. This caused Maven performance tests to always time out on the first loop (Maven needs ~38s just to compile), resulting in "best of 1 runs" benchmarks with unreliable results. Change the condition to apply the longer timeout for all Java test frameworks: junit4, junit5, and testng. Both the behavioral test runner and the benchmarking test runner are fixed. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…rations The line profiler's class detection only checked for "public class " or "class " prefixes, failing to match declarations with additional modifiers like "public final class". This caused the profiler class to be inserted before the package statement (at index 0), producing illegal Java code. Use a regex pattern that handles any combination of Java modifiers (public, private, protected, final, abstract, static, sealed, non-sealed) before class/interface/enum/record declarations. Also removed an unused variable (instrumented_source) that was computed but never referenced. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Two fixes: 1. Line profiler class detection: The regex only matched "public class" or "class" prefixes, failing on declarations with modifiers like "public final class". Use a regex that handles any combination of Java modifiers before class/interface/enum/record declarations. 2. Line profiler timeout: The dispatcher passed INDIVIDUAL_TESTCASE_TIMEOUT (15s) directly to the Java line profiler test runner, which used `timeout or 120` (truthy 15 doesn't trigger the 120s fallback). Apply JAVA_TESTCASE_TIMEOUT consistently for all Java test phases, and use max() instead of `or` for the Java default timeout. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…tern Same bug as the line profiler timeout: `timeout or max(120, ...)` doesn't trigger the fallback when timeout is a truthy low value like 15. Use max() to ensure Maven always gets at least 120 seconds. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…imeout The upstream omni-java branch already implemented a cleaner version of the line profiler timeout fix (with min_timeout variable and debug logging). Keep their version since it achieves the same goal. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…t-guard fix(java): fix Java instrumentation, JPMS, and timeout bugs for QuestDB
## Changes ### Debug Logging Added - parse_test_output.py: Added [RESOLVE], [PARSE-XML] logs for test file resolution - function_optimizer.py: Added [JAVA-ROOT], [WRITE-PATH], [REGISTER] logs - Traces complete flow from test generation → writing → registration → execution → parsing ### Bug Fixes 1. function_optimizer.py (lines 1855-1877): Fixed missing test_string parameter - Read test file content before passing to instrument_existing_test() - Pass test_string with test_path as optional parameter 2. java/support.py (lines 294-296): Fixed incorrect parameters in wrapper - Use named parameters matching new instrument_existing_test() signature - Removed obsolete call_positions, tests_project_root, analyzer parameters ## Testing - Added debug logs confirmed working in Fibonacci optimization - Test files written to correct locations with proper instrumentation - TestFile registry contains accurate paths - Ready for aerospike-client-java validation Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
…tures Enhanced _get_java_sources_root() to handle projects where tests_root points to a module directory that contains a 'src' subdirectory (e.g., test/src). Added checks for: 1. tests_root already ending with "src" (already a sources root) 2. Simple "src" subdirectory before checking Maven-standard src/test/java This fixes the base_dir mismatch bug where tests were written to the wrong directory in multi-module Maven projects like aerospike-client-java. Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
…e-dir-mismatch fix: Java behavior test execution in multi-module Maven projects
In --all mode, stale line numbers in FunctionToOptimize caused InvalidJavaSyntaxError when a prior optimization modified the same file. Now extract_function_source re-parses with tree-sitter to find methods by name, matching how Python (jedi) and Java replacement already work. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
[Fix] Java asserts removal
…s-all-mode fix: use tree-sitter name-based lookup for Java function extraction
…_context_extractor
…ns from tests - Implement add_global_declarations for JavaSupport to insert new class fields and helper methods from optimized code before function replacement - Remove inner_iterations kwarg from test_run_and_parse.py (removed from run_and_parse_tests in main), use CODEFLASH_INNER_ITERATIONS env var instead
…ks with protocol - Add test_string param to PythonSupport.instrument_existing_test and pass it from function_optimizer (fixes inject_profiling_into_existing_test missing arg error) - Add adjust_test_config_for_discovery to JavaSupport (sets tests_project_rootdir = tests_root) - Fix discover_functions calls in test_support.py and test_integration.py to use (source, file_path) protocol signature - Remove stale is_python mock in test_java_tests_project_rootdir.py (set_current_language already handles routing) - Fix test_java_e2e.py to use Java context extraction instead of Python's
The merge from main removed the is_java() branch in resolve_test_file_from_class_path that converts Java class paths (com.example.TestClass) to file paths (com/example/TestClass.java). Without it, JUnit XML parsing can't find instrumented test files.
Java needs prepare_module to return ValidCode without AST parsing, same as JavaScript. Without it, the optimizer skips all Java functions with "preparation error".
The merge from main stripped ~270 lines of Java-specific parsing logic from parse_test_output.py including: - Java test file resolution from class paths - Java timing marker parsing (5-field format vs Python's 6-field) - Java fallback stdout parsing for JUnit Console Launcher - Java SQLite result handling with Gson serialization - JaCoCo coverage loading - Java performance stdout preservation Restored the omni-java version which has all Java support intact alongside the existing Python and JS parsing.
…egression fixes - Create JavaFunctionOptimizer with get_code_optimization_context and replace_function_and_helpers_with_optimized_code (fixes NotImplementedError crash in java-fibonacci CI) - Add function_optimizer_class and process_generated_test_strings to JavaSupport - Fix missing testing_type param in parse_test_results call - Fix Java existing test path suffix mismatch (__perfinstrumented → __existing_perfinstrumented) - Clean up stale SQLite files in test_behavior_mode_writes_to_sqlite
… runner The Java runner was always overriding CODEFLASH_INNER_ITERATIONS with its default parameter (10), clobbering the value set by callers via test_env. Now only sets the default when test_env doesn't already provide it.
The optimization replaces an `if "key" in dict` check followed by a separate `dict[key]` access in `file_to_path()` with a single try/except on KeyError, halving the dictionary operations in the 99% cache-hit path (from ~47% + 38% profiler time to ~71% in one lookup). It also guards two expensive logger calls—one constructing a large f-string with the entire `optimized_code` object—behind `isEnabledFor(DEBUG/WARNING)` checks, preventing format-string evaluation when logging is disabled. Line profiler shows the warning path dropped from 65.6% to 74.8% of total time, but because it fires on only 18 of 3136 calls the overall function runtime improved 13%, dominated by the dictionary micro-optimization on the hot cache-hit loop.
Duplicate Code Detection ResultsFound 5 duplicates that should be consolidated: 1. escapeJson() method (HIGH confidence)Locations:
What's duplicated: Identical 7-line JSON string escaping function that handles backslashes, quotes, and control characters. Suggestion: Extract to a shared utility class (e.g., 2. remove_test_functions_from_generated_tests() (HIGH confidence)Locations:
What's duplicated: Identical 18-line method that iterates over generated tests, removes specified functions, and rebuilds the Suggestion: Extract to 3. add_runtime_comments_to_generated_tests() (HIGH confidence)Locations:
What's duplicated: Nearly identical 26-line method that builds runtime maps and adds performance comments to generated tests. Only difference is JavaScript version passes Suggestion: Extract to a base class or shared utility. The minor difference in 4. _build_runtime_map() (MEDIUM confidence)Locations:
What's duplicated: Core logic for building test invocation ID → runtime mapping is ~80% identical. Both construct qualified names, parse iteration IDs, and aggregate runtimes. JavaScript version has additional path resolution logic. Suggestion: Extract shared logic to base class. JavaScript can override to add its path-specific handling while inheriting the common qualified name and iteration parsing logic. 5. Java build tool detection (MEDIUM confidence)Locations:
What's duplicated: Logic that checks for Suggestion: Consolidate into Summary:
|
7f96d61 to
7b8169d
Compare
|
⚡️ This pull request contains optimizations for PR #1717
If you approve this dependent PR, these changes will be merged into the original PR branch
prepare-java-support-2.📄 14% (0.14x) speedup for
get_optimized_code_for_moduleincodeflash/languages/code_replacer.py⏱️ Runtime :
44.5 milliseconds→39.1 milliseconds(best of23runs)📝 Explanation and details
The optimization replaces an
if "key" in dictcheck followed by a separatedict[key]access infile_to_path()with a single try/except on KeyError, halving the dictionary operations in the 99% cache-hit path (from ~47% + 38% profiler time to ~71% in one lookup). It also guards two expensive logger calls—one constructing a large f-string with the entireoptimized_codeobject—behindisEnabledFor(DEBUG/WARNING)checks, preventing format-string evaluation when logging is disabled. Line profiler shows the warning path dropped from 65.6% to 74.8% of total time, but because it fires on only 18 of 3136 calls the overall function runtime improved 13%, dominated by the dictionary micro-optimization on the hot cache-hit loop.✅ Correctness verification report:
🌀 Click to see Generated Regression Tests
To edit these changes
git checkout codeflash/optimize-pr1717-2026-03-02T18.58.47and push.