私は、OpenCV、HALCON などを拡張する画像処理ライブラリに取り組んでいます。ライブラリは .NET Framework 3.5 である必要があり、.NET の経験が限られているため、パフォーマンスに関していくつか質問したいと思います。
私は自分自身に適切に説明できないいくつかの特定の事柄に遭遇しました.a)理由とb)ケースに対処するためのベストプラクティスは何ですか.
私の最初の質問は、Math.pow についてです。私はすでにいくつかの回答を StackOverflow で見つけましたが、これは非常によく説明されています (a) が、これについて何をすべきか (b) はわかりません。私のベンチマークプログラムは次のようになります
Stopwatch watch = new Stopwatch(); // from the Diagnostics class
watch.Start();
for (int i = 0; i < 1000000; i++)
double result = Math.Pow(4,7) // the function call
watch.Stop()
結果はあまり良くありませんでした (私のコンピューターでは約 300 ミリ秒) (テストを 10 回実行し、平均値を計算しました)。
私の最初のアイデアは、これが静的関数であるためかどうかを確認することでした。だから私は自分のクラスを実装しました
class MyMath
{
public static double Pow (double x, double y) //Using some expensive functions to calculate the power
{
return Math.Exp(Math.Log(x) * y);
}
public static double PowLoop (double x, int y) // Using Loop
{
double res = x;
for(int i = 1; i < y; i++)
res *= x;
return res;
}
public static double Pow7 (double x) // Using inline calls
{
return x * x * x * x * x * x * x;
}
}
私がチェックした 3 番目のことは、Math.Pow(4,7) を 4*4*4*4*4*4*4 で直接置き換えるかどうかでした。
結果は (10 回のテスト実行の平均)
300 ms Math.Pow(4,7)
356 ms MyMath.Pow(4,7) //gives wrong rounded results
264 ms MyMath.PowLoop(4,7)
92 ms MyMath.Pow7(4)
16 ms 4*4*4*4*4*4*4
現在、私の状況は基本的に次のようになっています。 Pow に Math を使用しないでください。私の唯一の問題はそれです...私は本当に自分のMathクラスを実装する必要がありますか? 累乗関数のためだけに独自のクラスを実装するのは、どういうわけか効果がないようです。(ちなみに、PowLoop と Pow7 はリリース ビルドでさらに 25% 高速ですが、Math.Pow はそうではありません)。
だから私の最後の質問は
a)Math.Powをまったく使用しない場合(ただし、分数の場合はおそらく)間違っています(これはなんとなく悲しくなります)。
b) 最適化するコードがある場合、そのような数学演算をすべて直接記述していますか?
c)数学演算用のより高速な(オープンソース^^)ライブラリがすでにあるかもしれません
d)私の質問のソースは基本的に次のとおりです。.NET Framework自体がすでに非常に最適化されたコードを提供し、そのような基本的な操作の結果をコンパイルすると仮定しました-それがMath-Classであろうと配列の処理であろうと、私は少し驚きました私は自分のコードを書くことで得をします。C#を直接信頼できないC#で、他に一般的な「フィールド」または何か他のものがありますか?