Skip to content

Commit a4ba32f

Browse files
committed
perf(segmentation): stop allocating a closure per claimed voxel
masksHolding and masksClearing.claim swept the reaching masks with some/forEach, so every voxel a brush or polygon fill walked allocated a fresh callback capturing i, j and k. Both now sweep the reaching masks with a plain indexed loop, so the per-voxel path allocates nothing. The answers are unchanged.
1 parent e8a2149 commit a4ba32f

1 file changed

Lines changed: 25 additions & 11 deletions

File tree

‎src/segmentation/masks/overlap.ts‎

Lines changed: 25 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -45,17 +45,26 @@ const masksReaching = (masks: BoundedScalars[], within: Extent3D) =>
4545
/**
4646
* Whether any of these masks holds the voxel at PARENT indices i, j, k, over
4747
* the box the caller is about to walk. Absent when no mask reaches that box.
48+
*
49+
* The answer is asked once per voxel the caller walks, so the sweep over the
50+
* reaching masks is a plain indexed loop: a callback taking i, j, k would be a
51+
* fresh closure per voxel.
4852
*/
4953
export function masksHolding(masks: BoundedScalars[], within: Extent3D) {
5054
const reaching = masksReaching(masks, within);
5155
if (reaching.length === 0) return undefined;
52-
return (i: number, j: number, k: number) =>
53-
reaching.some(
54-
(bounded) =>
56+
return (i: number, j: number, k: number) => {
57+
for (let index = 0; index < reaching.length; index += 1) {
58+
const bounded = reaching[index];
59+
if (
5560
extentContainsIndex(bounded.extent, i, j, k) &&
5661
bounded.scalars[maskOffset(bounded, i, j, k)] !==
5762
LABELMAP_BACKGROUND_VALUE
58-
);
63+
)
64+
return true;
65+
}
66+
return false;
67+
};
5968
}
6069

6170
/**
@@ -70,14 +79,19 @@ export function masksClearing(masks: BoundedScalars[], within: Extent3D) {
7079
const reaching = masksReaching(masks, within);
7180
if (reaching.length === 0) return undefined;
7281
const changed = new Set<vtkLabelMap>();
82+
// Indexed loop, as in masksHolding: claim runs once per voxel the caller
83+
// walks, and a callback over the reaching masks would allocate per voxel.
7384
const claim = (i: number, j: number, k: number) => {
74-
reaching.forEach((bounded) => {
75-
if (!extentContainsIndex(bounded.extent, i, j, k)) return;
76-
const offset = maskOffset(bounded, i, j, k);
77-
if (bounded.scalars[offset] === LABELMAP_BACKGROUND_VALUE) return;
78-
bounded.scalars[offset] = LABELMAP_BACKGROUND_VALUE;
79-
changed.add(bounded.mask);
80-
});
85+
for (let index = 0; index < reaching.length; index += 1) {
86+
const bounded = reaching[index];
87+
if (extentContainsIndex(bounded.extent, i, j, k)) {
88+
const offset = maskOffset(bounded, i, j, k);
89+
if (bounded.scalars[offset] !== LABELMAP_BACKGROUND_VALUE) {
90+
bounded.scalars[offset] = LABELMAP_BACKGROUND_VALUE;
91+
changed.add(bounded.mask);
92+
}
93+
}
94+
}
8195
return true;
8296
};
8397
return {

0 commit comments

Comments
 (0)