我正在研究擴展OpenCV,HALCON,...的n圖像處理庫。該庫必須使用.NET Framework 3.5,因爲我對.NET的使用經驗有限,所以我想問一些關於性能的問題。Math.Pow的最佳做法
我遇到了一些我無法向自己正確解釋的具體事情,並希望您提問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次,calcuated平均值)。
我的第一個想法是檢查這是因爲它是一個靜態函數。所以,我實現了我自己的直接階級
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;
}
}
我檢查的第三件事是,如果我將取代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
現在我的情況現在基本上是這樣的:不要使用數學的戰俘。我唯一的問題就是......我真的必須現在實施我自己的Math-Class嗎?爲功能函數實現一個自己的類似乎不太有效。 (順便說一下,PowLoop和Pow7在Release版本中的速度更快了25%,而Math.Pow則沒有)。
所以我最後的問題是
一)我,如果我不能在所有(但可能分數)(這讓我莫名其妙地傷心難過)使用Math.Pow我錯了。 b)如果你有代碼優化,你是否真的直接寫這些數學運算?
c)是有可能已經快(開源^^)庫數學運算
d)我的問題的來源基本上是:我認爲在.NET Framework本身就已經提供了非常優化編碼/編譯這些基本操作的結果 - 無論是數學類還是處理數組,我都有點驚訝,通過編寫自己的代碼可以獲得多少好處。還有其他的一些「領域」或別的東西在C#中看不到,我不能直接相信C#。
我認爲4 * 4 * 4 * 4 * 4 * 4 * 4會在編譯時評估,因此它的速度非常快。 – Nick 2011-03-04 10:13:54
我認爲對於大多數人來說,100ms左右並不是什麼大不了的事情。 C#通常不是大多數人的這種應用程序的首選。 – Ian 2011-03-04 10:15:26
你用較大的數字測試過嗎?我認爲Math.Pow針對較大的指數進行了優化,並且執行如下操作:x^7 == x^{3 + 3 + 1} == {x^3 + x^3 x},這意味着它正在運行順序是O(log(n)),而你的解決方案是O(n),並且對於大型指數可能會慢得多。 – markijbema 2011-03-04 10:19:01