⚡️ Speed up function is_build_output_dir by 141% in PR #1288 (fix/js-test-framework-detection)#1290
Closed
codeflash-ai[bot] wants to merge 1 commit intofix/js-test-framework-detectionfrom
Conversation
The optimized code achieves a **141% speedup** (from 590μs to 244μs) through three key optimizations:
**1. Eliminated repeated set construction**
The original code recreated the `build_dirs` set on every function call. Moving it to a module-level `frozenset` constant (`BUILD_DIRS`) eliminates this overhead entirely. The line profiler shows this saved ~160ns per call (5.3% of original runtime).
**2. Replaced expensive string conversion with native Path API**
The original used `path.as_posix().split("/")` which:
- Converts the Path to a POSIX string representation
- Allocates a new string
- Splits it into a list of parts
The optimized version uses `path.parts`, which directly returns a tuple of path components without any string conversion or allocation. This alone saved ~1.68μs per call (55.9% of original runtime), making it the single biggest performance gain.
**3. Early-exit explicit loop vs generator expression**
Replacing `any(part in BUILD_DIRS for part in parts)` with an explicit loop enables early exit as soon as a build directory is found. While `any()` also short-circuits, the explicit loop avoids generator object creation overhead. The line profiler shows the loop overhead is now distributed across multiple lines but totals less time than the original `any()` expression.
**Performance characteristics from test results:**
- **Shallow paths** (2-3 components): ~2-2.5x faster consistently
- **Deep paths without build dirs** (100 levels): ~2.5x faster due to avoiding string allocation on every check
- **Early matches**: Up to **7x faster** when build directory appears first (703% speedup for repeated "build" directories), demonstrating the power of early exit
- **Late matches**: Still ~2.5x faster, showing the string conversion savings dominate even without early exit
The optimization is particularly effective for codebases with deep directory structures or when scanning many paths, as each path check now uses native tuple operations instead of string manipulation.
3 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
⚡️ This pull request contains optimizations for PR #1288
If you approve this dependent PR, these changes will be merged into the original PR branch
fix/js-test-framework-detection.📄 141% (1.41x) speedup for
is_build_output_dirincodeflash/setup/detector.py⏱️ Runtime :
590 microseconds→244 microseconds(best of180runs)📝 Explanation and details
The optimized code achieves a 141% speedup (from 590μs to 244μs) through three key optimizations:
1. Eliminated repeated set construction
The original code recreated the
build_dirsset on every function call. Moving it to a module-levelfrozensetconstant (BUILD_DIRS) eliminates this overhead entirely. The line profiler shows this saved ~160ns per call (5.3% of original runtime).2. Replaced expensive string conversion with native Path API
The original used
path.as_posix().split("/")which:The optimized version uses
path.parts, which directly returns a tuple of path components without any string conversion or allocation. This alone saved ~1.68μs per call (55.9% of original runtime), making it the single biggest performance gain.3. Early-exit explicit loop vs generator expression
Replacing
any(part in BUILD_DIRS for part in parts)with an explicit loop enables early exit as soon as a build directory is found. Whileany()also short-circuits, the explicit loop avoids generator object creation overhead. The line profiler shows the loop overhead is now distributed across multiple lines but totals less time than the originalany()expression.Performance characteristics from test results:
The optimization is particularly effective for codebases with deep directory structures or when scanning many paths, as each path check now uses native tuple operations instead of string manipulation.
✅ Correctness verification report:
🌀 Click to see Generated Regression Tests
🔎 Click to see Concolic Coverage Tests
To edit these changes
git checkout codeflash/optimize-pr1288-2026-02-03T06.26.27and push.