@matt.mccormick, @phcerdan I just did a performance comparison between “old-school” and new range-based neighborhood iteration, both doing zero-padding (constant boundary). Using Visual C++ 2017 64-bit Release, I observed that the range-based neighborhood iteration implemented by http://review.source.kitware.com/#/c/23795/7 can be more than twice as fast as the “old-school” iteration
The new range-based neighborhood iteration was tested by the following function. It calculates a number, sumOfNeighbors
, just so that the optimizer cannot eliminate all the work.
unsigned TestRangeBasedIteration(const ImageType& image, const SizeType& radius)
{
using namespace itk::Experimental;
using RangeType = ShapedImageNeighborhoodRange<const ImageType,
ConstantBoundaryImageNeighborhoodPixelAccessPolicy<ImageType>>;
const auto region = image.GetBufferedRegion();
const auto imageSize = region.GetSize();
const auto offsets = GenerateRectangularImageNeighborhoodOffsets(radius);
RangeType range{ image, IndexType{}, offsets };
IndexType index{};
unsigned sumOfNeighbors = 0;
for (auto i = region.GetNumberOfPixels(); i > 0; --i)
{
range.SetLocation(index);
for (const PixelType neighbor : range)
{
sumOfNeighbors += neighbor;
}
GoToNextPixelIndex(index, imageSize);
}
return sumOfNeighbors;
}
And the old-school neighborhood iteration was tested by the following function:
unsigned TestOldSchoolIteration(const ImageType& image, const SizeType& radius)
{
using NeighborhoodIteratorType = itk::ConstNeighborhoodIterator<ImageType,
itk::ConstantBoundaryCondition<ImageType>>;
const auto region = image.GetBufferedRegion();
const auto imageSize = region.GetSize();
NeighborhoodIteratorType neighborhoodIterator(radius, &image, region);
const auto numberOfNeigbors = neighborhoodIterator.Size();
unsigned sumOfNeighbors = 0;
while (!neighborhoodIterator.IsAtEnd())
{
for (itk::SizeValueType i = 0; i < numberOfNeigbors; ++i)
{
sumOfNeighbors += neighborhoodIterator.GetPixel(i);
}
++neighborhoodIterator;
}
return sumOfNeighbors;
}
The full test is at https://gist.github.com/N-Dekker/eb94ba817b2a16e75d5e7c3fe54ec66f
Please check if you find it a fair comparison!