アレイに追加または削除がある場合は、平均値を最初から再計算するとかなり時間がかかることがあります。
その場合、代わりに実行中の平均を計算する価値があります。
合計の計算が便利な場合は、丸め誤差を回避し、正確な平均を計算できます。
function RecalcAverage(var RunningTotal: Int64; const OldArray, Additions, Deletions: TIntArray): double; overload;
var
i: integer;
begin
for i:= 0 to Length(Deletions) -1 do begin
RunningTotal:= RunningTotal - Deletions[i];
end;
for i:= 0 to Length(Additions) -1 do begin
RunningTotal:= RunningTotal + Additions[i];
end;
Result:= RunningTotal/(Length(OldArray) + Length(Additions) - Length(Deletions));
end;
パフォーマンスが問題であれば、必要な値をすべて1ループで計算するほうがはるかに意味があります。
type
TStats = record
MaxVal: integer;
MinVal: integer;
Average: double;
end;
function CalcStats(const input: TIntArray): TStats;
var
MinVal, MaxVal: integer;
Total: Int64;
i: integer;
begin
Assert(Length(input) > 0);
MinVal:= input[0];
MaxVal:= MinVal;
Total:= MinVal;
for i:= 1 to Length(input) -1 do begin
MinVal:= Min(MinVal, input[i]);
MaxVal:= Max(MinVal, input[i]);
Total:= Total + input[i];
end;
Result.MinVal:= MinVal;
Result.MaxVal:= MaxVal;
Result.Average:= Total/Length(input);
end;
は、私はちょうどベルリンの 'SumInt'で見ていたし、それが少し速く、物事を作るために(などのループ展開、)フープを介してジャンプがそれは、基本的にあなたがそうであるように同じことを行います。オフになっていてもオーバーフローチェックをオンにします(その後の前の状態に戻します)。だから著者はこれも考慮しなければならなかった。 FWIW、最速ではありませんが、コピーを作成して配列をソートすると、それ以外の場合に起こりうるオーバーフローを回避できます。また、非常に早くオーバーフローを検出することもできます。結局のところ、Meanの結果はオーバーフローすることができないので、オーバーフローせずにこれを行うことが可能でなければなりません。 –