This seems right to me. I made a C++Builder version of the Delphi code and I think it’s interesting.
[NB I haven’t spent much time yet closely verifying any of the output produced]
First observation, c++ runs faster. (10 million operations)
O[i] := CompassDirnByBinary ( data[i] ); // delphi = 140 ms // c++ = 100 ms
O[i] := CompassDirectionOf2 ( data[i] ); // delphi = 170 ms // c++ = 100 ms
O[i] := CompassDirectionOf3 ( data[i] ); // delphi = 180 ms // c++ = 40 ms
Second, in c++ there was no performance disadvantage to a normal loop like this.
for var cd := cdNorth to cdNNW do
if I < CompPoints[cd] then begin
Result := cd;
Exit;
end;
(otoh - c++ downside - they don’t entirely gel with enum-indexed arrays.)
Last point. I took @Scott_Sedgwick 's calculation approach, but divided by 32, and used an appropriate array.
const
halfpoints : array [ 0..31 ] of TCompassDirection
= ( cdNorth, cdNNE, cdNNE, cdNE, cdNE, cdENE, cdENE,
cdEast, cdEast, cdESE, cdESE, cdSE, cdSE, cdSSE, cdSSE,
cdSouth, cdSouth, cdSSW, cdSSW, cdSW, cdSW, cdWSW, cdWSW,
cdWest, cdWest, cdWNW, cdWNW, cdNW, cdNW, cdNNW, cdNNW, cdNorth );
In Delphi it slightly decreased the performance.
In C++ … it vastly increased performance.
From looking at the binary structure of the doubles, I also don’t think there should be any need for rounding when the division is by 16 or 32. I don’t think there’s any data being lost there.
My starting point, initial idea had been to try to get to integer operations instead of floating point ones.
But it looks like floating point operations can run pretty bloody fast, and you just have to try to get out of the cpu’s way as much as possible.
EDIT … I had to think about why there was a difference between Scott’s div 16 function and the div 32.
There isn’t any reason for them to be different … and it comes down to a cast to an enum vs an index into an array.
Interesting that the second is much faster in c++ than the first. And in Delphi they are about the same.
Changing the return expression yields the same 40 ms result with Scott’s function in c++.
const TCompassDirection points [ 16 ]
= { cdNorth, cdNNE, cdNE, cdENE,
cdEast, cdESE, cdSE, cdSSE,
cdSouth, cdSSW, cdSW, cdWSW,
cdWest, cdWNW, cdNW, cdNNW };