0
votes

I've got a "send" routine in Delphi 6 that accepts a variable-sized block of data (a fixed-size header followed by varying amounts of data) and the routine eventually calls sendto() in Winsock. I've coded it two ways, once where the passed block is a var (somewhat misleading, but it works) and once where a pointer to the block is passed. A simple version used for benchmarking looks something like:

type 
  header = record destination, serialnumber: integer end;
  pheader = ^header;

var
  smallblock: record h: header; data: array[1..5] of integer end;
  bigblock: record h: header; data: array[1..100] of integer end;

procedure send1(var h: header; size: integer);
begin
h.destination := 1; // typical header adjustments before sendto()
h.serialnumber := 2;
sendto(sock, h, size, 0, client, sizeof(client))
end;

procedure send2(p: pheader; size: cardinal);
begin
p^.destination := 1;
p^.serialnumber := 2;
sendto(sock, p^, size, 0, client, sizeof(client))
end;

procedure doit1;
begin
send1(smallblock.h, sizeof(smallblock));
send1(bigblock.h, sizeof(bigblock));
end;

procedure doit2;
begin
send2(@smallblock, sizeof(smallblock));
send2(@bigblock, sizeof(bigblock));
end;

The "send" routine will be called often, with many different block sizes, and should be as fast as possible. After doing a few runs of some simple benchmarks (by timing calls with gettickcount), the pointer technique (doit2) seems to run about 3% faster on my machine than the var technique (doit1), although I don't see any real difference between the two techniques in the object code (not that I'm an assembler guru).

Is the 3% an illusion due to my crude benchmarks, or is the pointer technique really beating the var technique?

1
@mikey: No, there isn't. :-) See my response to you in Remy's answer.Ken White
3% is a humongous difference. Check your benchmarks.Vector

1 Answers

7
votes

There is no performance difference passing a var parameter versus a pointer parameter. They do exactly the same thing (pass a memory address), and compile to similar, if not identical, assembly code. So any benchmarking differences are likely to be caused by issues in the benchmarking itself, not in the code that is being benchmarked. GetTickCount() is not exactly the best benchmarking tool, for instance. The best way to time your code is to use an external profiler, like AQTime.

BTW, your doit2() test should be like this instead:

procedure doit2;
begin
  send2(@(smallblock.h), sizeof(smallblock));
  send2(@(bigblock.h), sizeof(bigblock));
end;