.NET数学计算性能 [英] .NET math calculation performances
问题描述
我问了一个有关将Excel的BetaInv函数移植到.NET的问题: SQL中的BetaInv函数服务器
I asked a question about having the Excel's BetaInv function ported to .NET: BetaInv function in SQL Server
现在,我设法用纯依赖性更少的C#代码编写了该函数,并且在逗号后最多6或7位数字的情况下,我的确获得了与MS Excel中相同的结果,结果对我们来说很好,问题在于此类代码已嵌入在SQL CLR函数中,它从存储过程中被调用了数千次,并使整个过程的执行速度降低了大约50%,从30秒到一分钟(如果我不使用该函数,则一分钟).
now I managed to write that function in pure dependency less C# code and I do get the same results than in MS Excel up to 6 or 7 digits after comma, results are fine for us, the problem is that such code is embedded in a SQL CLR Function and gets called thousands of time from a stored procedure and makes the execution of the whole procedure about 50% slower, from 30 seconds up to a minute if I use that function or not.
这是其中的一些代码,我并没有要求进行深入的分析,但是是否有人在进行此计算时看到任何主要的性能问题?例如使用其他数据类型,而不是使用double或其他类型...?
here some code of it, I am not asking a deep analysis but is there anybody who sees any major performance issue in the way I am doing this calculations? like for example usage of other data types instead of doubles or whatsoever... ?
private static double betacf(double a, double b, double x)
{
int m, m2;
double aa, c, d, del, h, qab, qam, qap;
qab = a + b;
qap = a + 1.0;
qam = a - 1.0;
c = 1.0; // First step of Lentz’s method.
d = 1.0 - qab * x / qap;
if (System.Math.Abs(d) < FPMIN)
{
d = FPMIN;
}
d = 1.0 / d;
h = d;
for (m = 1; m <= MAXIT; ++m)
{
m2 = 2 * m;
aa = m * (b - m) * x / ((qam + m2) * (a + m2));
d = 1.0 + aa * d; //One step (the even one) of the recurrence.
if (System.Math.Abs(d) < FPMIN)
{
d = FPMIN;
}
c = 1.0 + aa / c;
if (System.Math.Abs(c) < FPMIN)
{
c = FPMIN;
}
d = 1.0 / d;
h *= d * c;
aa = -(a + m) * (qab + m) * x / ((a + m2) * (qap + m2));
d = 1.0 + aa * d; // Next step of the recurrence (the odd one).
if (System.Math.Abs(d) < FPMIN)
{
d = FPMIN;
}
c = 1.0 + aa / c;
if (System.Math.Abs(c) < FPMIN)
{
c = FPMIN;
}
d = 1.0 / d;
del = d * c;
h *= del;
if (System.Math.Abs(del - 1.0) < EPS)
{
// Are we done?
break;
}
}
if (m > MAXIT)
{
return 0;
}
else
{
return h;
}
}
private static double gammln(double xx)
{
double x, y, tmp, ser;
double[] cof = new double[] { 76.180091729471457, -86.505320329416776, 24.014098240830911, -1.231739572450155, 0.001208650973866179, -0.000005395239384953 };
y = xx;
x = xx;
tmp = x + 5.5;
tmp -= (x + 0.5) * System.Math.Log(tmp);
ser = 1.0000000001900149;
for (int j = 0; j <= 5; ++j)
{
y += 1;
ser += cof[j] / y;
}
return -tmp + System.Math.Log(2.5066282746310007 * ser / x);
}
推荐答案
对我来说唯一突出的一点是,通常是对性能的影响,是内存分配.我不知道 gammln
的调用频率,但是您可能希望将 double [] cof = new double [] {}
移至静态的一次性分配.
The only thing that stands out for me, and is usually a performance hit, is memory allocation. I don't know how often gammln
is called but you might want to move the double[] cof = new double[] {}
to a static one time only allocation.
这篇关于.NET数学计算性能的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!