Skip to content

Instantly share code, notes, and snippets.

@maarzt
Created May 22, 2020 15:31
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save maarzt/19167a5019c1d685c483441b7322b986 to your computer and use it in GitHub Desktop.
Save maarzt/19167a5019c1d685c483441b7322b986 to your computer and use it in GitHub Desktop.
Benchmark comparing the performance of ImgLib2 Cursor agains LoopBuilder
import net.imglib2.Cursor;
import net.imglib2.img.Img;
import net.imglib2.img.array.ArrayImg;
import net.imglib2.img.array.ArrayImgs;
import net.imglib2.img.cell.CellImg;
import net.imglib2.img.cell.CellImgFactory;
import net.imglib2.img.planar.PlanarImg;
import net.imglib2.img.planar.PlanarImgs;
import net.imglib2.loops.LoopBuilder;
import net.imglib2.type.numeric.real.FloatType;
import net.imglib2.view.Views;
import org.openjdk.jmh.annotations.Benchmark;
import org.openjdk.jmh.annotations.Fork;
import org.openjdk.jmh.annotations.Measurement;
import org.openjdk.jmh.annotations.Scope;
import org.openjdk.jmh.annotations.State;
import org.openjdk.jmh.annotations.Warmup;
import org.openjdk.jmh.runner.Runner;
import org.openjdk.jmh.runner.RunnerException;
import org.openjdk.jmh.runner.options.Options;
import org.openjdk.jmh.runner.options.OptionsBuilder;
import java.util.concurrent.TimeUnit;
/**
* A benchmark, that compares the performance of two implementations of a copy method.
* One method was implemented using ImgLib2 {@link Cursor}. The other method was
* implemented using {@link LoopBuilder}.
* <p>
* The benchmark is done using JMH (https://openjdk.java.net/projects/code-tools/jmh/)
* <p>
* Benchmark result on a Dell XPS 15 (higher is better):
* <pre>
* LoopBuilderPerformanceProofBenchmark.benchmarkCursors thrpt 10 6.498 ± 0.120 ops/s
* LoopBuilderPerformanceProofBenchmark.benchmarkCursorsArrayImg thrpt 10 167.155 ± 3.356 ops/s
* LoopBuilderPerformanceProofBenchmark.benchmarkLoopBuilder thrpt 10 23.532 ± 2.581 ops/s
* LoopBuilderPerformanceProofBenchmark.benchmarkLoopBuilderArrayImg thrpt 10 165.178 ± 8.547 ops/s
* </pre>
* The measurements show that Cursors and LoopBuilder perform equally well,
* when only {@link ArrayImg} is used as image type.
* But LoopBuilder is four times faster than Cursors, when multiple
* image types ({@link ArrayImg}, {@link CellImg}, {@link PlanarImg} are used.
*/
@Fork( 1 )
@Warmup( iterations = 10, time = 100, timeUnit = TimeUnit.MILLISECONDS )
@Measurement( iterations = 10, time = 100, timeUnit = TimeUnit.MILLISECONDS )
@State( Scope.Benchmark )
public class LoopBuilderPerformanceDemo
{
private static void copyCursors( Img< FloatType > source, Img< FloatType > target )
{
Cursor< FloatType > sourceCursor = Views.flatIterable( source ).cursor();
Cursor< FloatType > targetCursor = Views.flatIterable( target ).cursor();
while ( sourceCursor.hasNext() )
targetCursor.next().set( sourceCursor.next() );
}
private static void copyLoopBuilder( Img< FloatType > source, Img< FloatType > target )
{
LoopBuilder.setImages( source, target ).forEachPixel( ( s, t ) -> t.set( s ) );
}
private final long[] dimensions = { 100, 100, 100 };
private final Img< FloatType > arrayImg = ArrayImgs.floats( dimensions );
private final Img< FloatType > planarImg = PlanarImgs.floats( dimensions );
private final Img< FloatType > cellImg = new CellImgFactory<>( new FloatType(), 10, 10, 10 ).create( dimensions );
private final Img< FloatType > arrayImgA = ArrayImgs.floats( dimensions );
private final Img< FloatType > arrayImgB = ArrayImgs.floats( dimensions );
private final Img< FloatType > arrayImgC = ArrayImgs.floats( dimensions );
@Benchmark
public void benchmarkCursorsArrayImg()
{
copyCursors( arrayImgA, arrayImgB );
copyCursors( arrayImgB, arrayImgC );
copyCursors( arrayImgC, arrayImgA );
}
@Benchmark
public void benchmarkCursors()
{
copyCursors( arrayImg, planarImg );
copyCursors( planarImg, cellImg );
copyCursors( cellImg, arrayImg );
}
@Benchmark
public void benchmarkLoopBuilderArrayImg()
{
copyLoopBuilder( arrayImgA, arrayImgB );
copyLoopBuilder( arrayImgB, arrayImgC );
copyLoopBuilder( arrayImgC, arrayImgA );
}
@Benchmark
public void benchmarkLoopBuilder()
{
copyLoopBuilder( arrayImg, planarImg );
copyLoopBuilder( planarImg, cellImg );
copyLoopBuilder( cellImg, arrayImg );
}
public static void main( String... args ) throws RunnerException
{
Options options = new OptionsBuilder().include( LoopBuilderPerformanceDemo.class.getSimpleName() ).build();
new Runner( options ).run();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment