我正在研究扩展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