Delphi 6 には、可変サイズのデータ ブロック (固定サイズのヘッダーの後にさまざまな量のデータが続く) を受け入れる「送信」ルーチンがあり、ルーチンは最終的に Winsock で sendto() を呼び出します。渡されたブロックが var である場合 (多少誤解を招きますが、機能します) と、ブロックへのポインターが渡される場合の 2 つの方法でコーディングしました。ベンチマークに使用される単純なバージョンは次のようになります。
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;
「送信」ルーチンは、さまざまなブロック サイズで頻繁に呼び出されるため、できるだけ高速にする必要があります。単純なベンチマークを数回実行した後 (gettickcount を使用して呼び出しのタイミングを調整することにより)、私のマシンではポインター手法 (doit2) が var 手法 (doit1) よりも約 3% 高速に動作するように見えますが、実際の違いは見られません。オブジェクト コードの 2 つの手法の間で (私がアセンブラーの第一人者であるというわけではありません)。
3% は私の大まかなベンチマークによる錯覚ですか、それともポインター手法は実際に var 手法を打ち負かしていますか?