Skip to content

perf(overlap): drop dead TP/FN/FP/TN pixel-map computation (~3x)#93

Closed
timtreis wants to merge 1 commit into
mainfrom
perf/overlap-speedup
Closed

perf(overlap): drop dead TP/FN/FP/TN pixel-map computation (~3x)#93
timtreis wants to merge 1 commit into
mainfrom
perf/overlap-speedup

Conversation

@timtreis

@timtreis timtreis commented Jul 6, 2026

Copy link
Copy Markdown
Collaborator

measureobjectoverlap computed TP/FN/FP/TN pixel maps (via the subscripts() set-intersection + maskimg() per-pixel-assignment helpers) and then never used them — the function returns results, which only holds the overlap measurements and the optional EMD. The four maps are assigned and discarded: never read, never added to results, never returned.

They're a verbatim carry-over from CellProfiler's MeasureObjectOverlap (which renders TP/FP/FN/TN as overlay images); cp_measure returns a feature dict, so they have no consumer here. The set(zip(...)) & set(zip(...)) intersection + per-pixel Python loop was ~2/3 of the function's runtime.

Deleting the dead block and the now-unused subscripts()/maskimg() helpers is output-identical and ~3× faster end-to-end (1024px/64 objects: 3140ms → 1060ms, 2.96×; verified allclose, all 19 test_multimask.py tests pass).

Net: −32 lines, no behavior change.

measureobjectoverlap computed TP/FN/FP/TN pixel maps (via the subscripts()
set-intersection + maskimg() per-pixel-assignment helpers) and then never used
them: the function returns `results`, which only holds the overlap measurements
and the optional EMD — the four maps are assigned and discarded, never read, never
added to results, never returned.

They are a verbatim carry-over from CellProfiler's MeasureObjectOverlap, which
renders TP/FP/FN/TN as overlay images; cp_measure returns a feature dict, so they
have no consumer here. The `set(zip(...)) & set(zip(...))` intersection plus the
per-pixel Python assignment loop was ~2/3 of the function's runtime.

Deleting the dead block and the now-unused subscripts()/maskimg() helpers is
output-identical and ~3x faster end-to-end (1024px/64 objects: 3140ms -> 1060ms,
2.96x; output verified allclose, 19 multimask tests pass).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@timtreis
timtreis requested a review from afermg July 6, 2026 13:43
@github-actions

github-actions Bot commented Jul 6, 2026

Copy link
Copy Markdown

Benchmark — 2cc23c8 vs main

speedup = main/head (>1 faster, <1 slower) · median per cell · showing functions that moved ≥1.05× either way

texture

size \ objects 16 64 256
256 1.10× 1.00× 1.01×
512 1.00× 0.99× 1.00×
1024 1.01× 1.00× 1.00×

zernike

size \ objects 16 64 256
256 0.94× 1.09× 1.04×
512 1.01× 1.01× 1.02×
1024 1.01× 0.99× 1.03×

@timtreis timtreis closed this Jul 6, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant