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.

Reply via email to