Skip to content

Comments

Avoid calling ImageConstIterator::GetIndex() iteratively, in transforms and metrics#1410

Merged
N-Dekker merged 5 commits intomainfrom
Use-iterator-WithIndex-when-calling-GetIndex
Feb 24, 2026
Merged

Avoid calling ImageConstIterator::GetIndex() iteratively, in transforms and metrics#1410
N-Dekker merged 5 commits intomainfrom
Use-iterator-WithIndex-when-calling-GetIndex

Conversation

@N-Dekker
Copy link
Member

@N-Dekker N-Dekker commented Feb 13, 2026

ImageConstIterator::GetIndex() is relatively expensive, as it computes the index with each call, by doing m_Image->ComputeIndex(m_Offset) internally.

This pull request avoids calling ImageConstIterator::GetIndex(), either by using an iterator "with index" (for example ImageRegionIteratorWithIndex), or by using an iterator "with only index" (ImageRegionConstIteratorWithOnlyIndex), instead.

Doing so should improve the performance of initialization of metrics. Moreover, it specifically improves the performance of the "DistancePreservingRigidityPenalty" and the "TransformRigidityPenalty" metric. It also improves the performance of the "BSplineTransformWithDiffusion" and the "MultiBSplineTransformWithNormal" transform.


See also:

When calling `it.GetIndex()` on each iteration, ITK's `ImageRegionIteratorWithIndex` is much faster than `ImageRegionIterator`.

This commit will improve the performance of the "TransformRigidityPenalty" metric.

Removed the unnecessary public `RigidityImageIteratorType = ImageRegionIterator` type alias.
When calling `it.GetIndex()` on each iteration, `ImageRegionIteratorWithIndex` is much faster than `ImageRegionIterator`.

This yields a performance improvement when using a mask. ComputeImageExtremaFilter is being used during the initialization of metrics.
When calling `it.GetIndex()` on each iteration, ITK's `ImageRegionIteratorWithIndex` is much faster than `ImageRegionIterator`.

This commit will improve the performance of the "MultiBSplineTransformWithNormal" transform.
@N-Dekker
Copy link
Member Author

Regarding the use of an iterator "With Index" (versus using an iterator without index), proposed for TransformRigidityPenaltyTerm, ComputeImageExtremaFilter, and MultiBSplineDeformableTransformWithNormal, I observed that ImageRegionConstIteratorWithIndex is much faster than ImageRegionConstIterator (without index), when both the index and the pixel value are retrieved iteratively. I tried the following for a large 2D image:

for (IteratorType it{ image, region }; !it.IsAtEnd(); ++it)
{
    const auto& index = it.GetIndex();
    result += it.Get() + (index[0] + index[1]) % 8;
}

Using VS2026, Release build and ITK v6.0b02, I observed that ImageRegionConstIterator (without index) can take twice as much time as ImageRegionConstIteratorWithIndex.

@N-Dekker
Copy link
Member Author

N-Dekker commented Feb 15, 2026

To my surprise, when only the index is retrieved, both ImageRegionConstIteratorWithIndex and ImageRegionConstIterator appear faster than ImageRegionIndexRange, on a large 2D image. (ImageRegionConstIteratorWithIndex is then almost 3x as fast as ImageRegionConstIterator, and almost 4x as fast as ImageRegionIndexRange.) 🤔


@N-Dekker N-Dekker force-pushed the Use-iterator-WithIndex-when-calling-GetIndex branch from 7e6a612 to fa75a2b Compare February 22, 2026 13:56
Iterative retrieval of n-dimensional index values is much faster when using `ImageRegionIteratorWithOnlyIndex` than when using a regular `ImageRegionIterator` (which "computes" the index with each iteration).

This commit will improve the performance of the "DistancePreservingRigidityPenalty" metric.
Iterative retrieval of n-dimensional index values is much faster when using `ImageRegionConstIteratorWithOnlyIndex` than when using a regular `ImageRegionConstIterator` (which "computes" the index with each iteration).

This commit will improve the performance of the "BSplineTransformWithDiffusion" transform.

Removed the nested `DummyIteratorType` typedef, that is no longer used by now.
@N-Dekker N-Dekker force-pushed the Use-iterator-WithIndex-when-calling-GetIndex branch from fa75a2b to fec8631 Compare February 22, 2026 14:01
@N-Dekker N-Dekker merged commit ce4bfc1 into main Feb 24, 2026
8 checks passed
@N-Dekker N-Dekker deleted the Use-iterator-WithIndex-when-calling-GetIndex branch February 24, 2026 09:37
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