diff --git a/.github/workflows/comment-profiling-changes.yaml b/.github/workflows/comment-profiling-changes.yaml index 9263bde252..f01a6e03d2 100644 --- a/.github/workflows/comment-profiling-changes.yaml +++ b/.github/workflows/comment-profiling-changes.yaml @@ -137,6 +137,7 @@ jobs: const sectionTitles = ['Compilation', 'Update', 'Run Once', 'Cached Execution']; let hasSignificantChanges = false; + let hasRegressions = false; let regressionDetails = []; for (let i = 0; i < allOutputs.length; i++) { @@ -153,19 +154,25 @@ jobs: if (isSignificantChange(diffPct, absoluteChange, outputName)) { hasSignificantChanges = true; - regressionDetails.push({ - module_path: benchmark.module_path, - id: benchmark.id, - diffPct, - absoluteChange, - sectionTitle - }); + + // Only an increase in instruction count is a regression; improvements must not fail CI. + if (diffPct > 0) { + hasRegressions = true; + regressionDetails.push({ + module_path: benchmark.module_path, + id: benchmark.id, + diffPct, + absoluteChange, + sectionTitle + }); + } } } } } core.setOutput('has-significant-changes', hasSignificantChanges); + core.setOutput('has-regressions', hasRegressions); core.setOutput('regression-details', JSON.stringify(regressionDetails)); - name: Comment PR @@ -319,7 +326,7 @@ jobs: } - name: Fail on significant regressions - if: steps.analyze.outputs.has-significant-changes == 'true' + if: steps.analyze.outputs.has-regressions == 'true' uses: actions/github-script@v8 with: script: | diff --git a/node-graph/libraries/rendering/src/renderer.rs b/node-graph/libraries/rendering/src/renderer.rs index c04d787592..de416a4d1b 100644 --- a/node-graph/libraries/rendering/src/renderer.rs +++ b/node-graph/libraries/rendering/src/renderer.rs @@ -1714,8 +1714,14 @@ fn extend_targets_from_vector(targets: &mut Vec, vector_list: &List } fn extend_free_point_targets(vector: &Vector, transform: DAffine2) -> impl Iterator + '_ { - vector.point_domain.ids().iter().filter_map(move |&point_id| { - if vector.any_connected(point_id) { + // Mark every point index touched by a segment endpoint in one `O(points + segments)` pass, avoiding a per-point `any_connected` scan + let mut connected = vec![false; vector.point_domain.len()]; + for &point_index in vector.segment_domain.start_point().iter().chain(vector.segment_domain.end_point()) { + connected[point_index] = true; + } + + vector.point_domain.ids().iter().enumerate().filter_map(move |(point_index, &point_id)| { + if connected[point_index] { return None; } diff --git a/node-graph/libraries/vector-types/src/vector/vector_attributes.rs b/node-graph/libraries/vector-types/src/vector/vector_attributes.rs index 58e6400ace..63f9b87650 100644 --- a/node-graph/libraries/vector-types/src/vector/vector_attributes.rs +++ b/node-graph/libraries/vector-types/src/vector/vector_attributes.rs @@ -1223,7 +1223,15 @@ impl Vector { } pub fn is_branching(&self) -> bool { - (0..self.point_domain.len()).any(|point_index| self.segment_domain.connected_count(point_index) > 2) + // Tally segment endpoints per point in one `O(points + segments)` pass, short-circuiting once any point exceeds two + let mut connected_count = vec![0_u8; self.point_domain.len()]; + for &point_index in self.segment_domain.start_point().iter().chain(self.segment_domain.end_point()) { + connected_count[point_index] += 1; + if connected_count[point_index] > 2 { + return true; + } + } + false } pub fn has_regions(&self) -> bool {