Re: Delphi Roadmap (by David I)



On Tue, 27 Sep 2005 22:33:31 +1000, "Oliver Townshend"
<oliveratzipdotcomdotau> wrote:

>Well I suppose that will get you the results you want. But it doesn't prove
>5x slower to me. Personally I'd rather see it demonstrated over a broad
>range of benchmarks.

I've made some small tests with code I actually use. I've tested this
with the most similar conditions I could, making sure the code does
not contain some obviously slow parts on either platform (ala the
string = string + char; issue).

The program(s) loads a bitmap, and applies a gaussian blur to it. It
displays the source and processed bitmaps in two TImages. The test
image was 4105x3182 pixels.

All runs were done outside of the IDE, and the two projects were
compiled using fully patched Delphi 2005, with optimizations on,
overflow and range checking off. Memory usage was observed using
Perfmon.

Under win32, my gaussian blur routine uses 3.0-3.1 seconds per run,
and a peak working set of about 240mb during 3 runs, dropping to 80mb
after processing had finished.

Under .net, the routine uses about 9.2-9.6 per seconds run, with a
peak working set of about 410mb during the 3 runs. After the third
run, however, the GC did not clean up memory, and it stayed at 410mb
for at least 30 seconds after processing had finished, at which time I
terminated the app.

In order to access the pixels of the bitmap, I copy the pixels into a
temporary buffer of singles. This also allows me to efficiently access
the entire image in .Net aswell. Under .Net this part took longer than
the actual pixel processing. Without copying to and from this buffer,
the .Net routine used only 4.3-4.5 seconds (vs ~2.5 for win32).

The core routine contains four similar loops looking like this (main
difference is source, dest, and count):

for i:= 0 to Count-1 do
begin
Buffer[bi].r:= (C.B * Src[si].r + (C.b1 * s1.r + C.b2 * s2.r + C.b3
* s3.r));
Buffer[bi].g:= (C.B * Src[si].g + (C.b1 * s1.g + C.b2 * s2.g + C.b3
* s3.g));
Buffer[bi].b:= (C.B * Src[si].b + (C.b1 * s1.b + C.b2 * s2.b + C.b3
* s3.b));

s3:= s2;
s2:= s1;
s1:= Buffer[bi];

inc(si, SrcDelta);
inc(bi);
end;

To me, it shows that one of the problems with .Net and speed, is when
you have to access memory in "special" ways.

If I had a native .Net bitmap loader which would allow direct access
to the pixel buffer, then the .Net code would only run ~3 times as
slow as the SSE optimized win32 code (which uses ~1.5 seconds), or
less than 2 times as slow as a "normal" win32 version.

I'd say this is a real world example. I use this code a lot, and if I
were to port my stuff to .net, it would look a lot similar to what I
used here. It is however just one :)

I'd also like to say that it was nice to see how easily I could port
the routine to .Net using VCL.Net. I had to modify my code to use
arrays instead of pointers, but thanks to SyncEdit it took no time at
all. I only had to write two small routines where I used different
code depending on platform (for copying the pixel data from and back
to a bitmap).

- Asbjørn
.



Relevant Pages

  • Re: Problem with SavePicture, and a question on new versions
    ... > mode does not have to be in pixels. ... 500 pixels then the picture box will also be 700 x 500 pixels. ... and the bitmap shows ... to be *smaller* than the scale units that the BitBlt API is using ...
    (comp.lang.basic.visual.misc)
  • Re: How long Win32 viable?
    ... >> monitor pixels. ... the pixel based world we have with the Win32 API approach to graphics. ... would translate your comment as meaning that your apps are designed for one ... expecially when the bitmap has a lot more pixels than the form it is ...
    (borland.public.delphi.non-technical)
  • Anti-aliasing idea for bitmap
    ... How to edit a button's bitmap so that only the button ... I load an 8-bit bitmap as a resource. ... and edit its pixels depending on which state the button is in. ... Problem: No anti-aliasing. ...
    (microsoft.public.win32.programmer.gdi)
  • Re: how to get a bitmap from the screen and then inside lisp?
    ... Getting pixels off the screen quickly is a bit complicated and you ... have to do some decoding of Windows bitmap data structures. ... int x, int y, int w, int h, ... // get the window handle ...
    (comp.lang.lisp)
  • Re: How to get an associated file icon without the Alpha Channel i
    ... no reason for keeping it around after the end of the routine anyway, just make the OLE picture object own the handle and there's no ... You don't need to select the colour bitmap into the temporary DC, GetDIBitsjust requires a device context handle rather than ... Rather than filling out the header structure yourself, you can use GetDIBits() to do this for you - have a look at chapter 3 of the ... When you're editing the mask data, you're attempting to operate on it in the same way as the colour data by getting GetDIBitsto ...
    (microsoft.public.vb.winapi)