Speed of horizontal flip

Rikki Cattermole via Digitalmars-d-learn digitalmars-d-learn at puremagic.com
Thu Apr 2 02:47:21 PDT 2015


On 2/04/2015 2:52 a.m., tchaloupka wrote:
> Hi,
> I have a bunch of square r16 and png images which I need to flip
> horizontally.
>
> My flip method looks like this:
> void hFlip(T)(T[] data, int w)
> {
>     import std.datetime : StopWatch;
>
>     StopWatch sw;
>     sw.start();
>
>     foreach(int i; 0..w)
>     {
>       auto row = data[i*w..(i+1)*w];
>       row.reverse();
>     }
>
>     sw.stop();
>     writeln("Img flipped in: ", sw.peek().msecs, "[ms]");
> }
>
> With simple r16 file format its pretty fast, but with RGB PNG
> files (2048x2048) I noticed its somewhat slow so I tried to
> compare it with C# and was pretty surprised by the results.
>
> C#:
> PNG load - 90ms
> PNG flip - 10ms
> PNG save - 380ms
>
> D using dlib (http://code.dlang.org/packages/dlib):
> PNG load - 500ms
> PNG flip - 30ms
> PNG save - 950ms
>
> D using imageformats
> (http://code.dlang.org/packages/imageformats):
> PNG load - 230ms
> PNG flip - 30ms
> PNG save - 1100ms
>
> I used dmd-2.0.67 with -release -inline -O
> C# was just with debug and VisualStudio attached to process for
> debugging and even with that it is much faster.
>
> I know that System.Drawing is using Windows GDI+, that can be
> used with D too, but not on linux.
> If we ignore the PNG loading and saving (didn't tried libpng
> yet), even flip method itself is 3 times slower - I don't know D
> enough to be sure if there isn't some more effecient way to make
> the flip. I like how the slices can be used here.
>
> For a C# user who is expecting things to just work as fast as
> possible from a system level programming language this can be
> somewhat disappointing to see that pure D version is about 3
> times slower.
>
> Am I doing something utterly wrong?
> Note that this example is not critical for me, it's just a simple
> hobby script I use to move and flip some images - I can wait. But
> I post it to see if this can be taken somewhat closer to what can
> be expected from a system level programming language.
>
> dlib:
> auto im = loadPNG(name);
> hFlip(cast(ubyte[3][])im.data, cast(int)im.width);
> savePNG(im, newName);
>
> imageformats:
> auto im = read_image(name);
> hFlip(cast(ubyte[3][])im.pixels, cast(int)im.w);
> write_image(newName, im.w, im.h, im.pixels);
>
> C# code:
> static void Main(string[] args)
>           {
>               var files = Directory.GetFiles(args[0]);
>
>               foreach (var f in files)
>               {
>                   var sw = Stopwatch.StartNew();
>                   var img = Image.FromFile(f);
>
>                   Debug.WriteLine("Img loaded in {0}[ms]",
> (int)sw.Elapsed.TotalMilliseconds);
>                   sw.Restart();
>
>                   img.RotateFlip(RotateFlipType.RotateNoneFlipX);
>                   Debug.WriteLine("Img flipped in {0}[ms]",
> (int)sw.Elapsed.TotalMilliseconds);
>                   sw.Restart();
>
>                   img.Save(Path.Combine(args[0], "test_" +
> Path.GetFileName(f)));
>                   Debug.WriteLine("Img saved in {0}[ms]",
> (int)sw.Elapsed.TotalMilliseconds);
>                   sw.Stop();
>               }
>           }


Assuming I've done it correctly, Devisualization.Image takes around 8ms 
in debug mode to flip horizontally using dmd. But 3ms for release.

module test;

void main() {
     import devisualization.image;
     import devisualization.image.mutable;
	import devisualization.util.core.linegraph;

     import std.stdio;

	writeln("===============\nREAD\n===============");
	Image img = imageFromFile("test/large.png");
	img = new MutableImage(img);

	import std.datetime : StopWatch;

	StopWatch sw;
	sw.start();

	foreach(i; 0 .. 1000) {
		img.flipHorizontal;
	}

	sw.stop();

	writeln("Img flipped in: ", sw.peek().msecs / 1000, "[ms]");
}

I was planning on doing this earlier. But I discovered a PR I pulled 
which fixed for 2.067 broke chunk types reading.


More information about the Digitalmars-d-learn mailing list