我有以下代码行:
SomeDouble= constant1/ ((a * b) * (Math.Asin((c- a) / (a * d)) + constant2))
这两个常数是不同的,并且从循环中计算出来,a-d是每次都改变的变量。
从表面上看,它的平均速度相差0.002ms(26,508,249次点击时为47,633.588s)。我遇到的问题是它将被称为数十亿次,每次运行软件时大约有200亿次点击。因此,如果我可以将其减少到0.001毫秒,那么差异就会很大。我知道分割是一个非常缓慢的过程,我希望计算arcsin也很慢。如果有人可以建议是否有更快的方法来计算arcsin或任何其他帮助来加速这行代码将是伟大的。关于vb.net的内置数学函数是否针对速度进行优化的任何建议都很好我注意到math.sqrt(somevalue)比(somevalue)^ 0.5快。
先谢谢!
答案 0 :(得分:2)
我会做一些测试,以确保Math.Asin确实是公式中最慢的部分。如果它相对于其他乘法和除法确实很慢,那么你可以尝试为Math.Asin实现自己的查找表。换句话说,提前计算数百万Math.Asin值,并将它们编码到您的程序中。这会换算程序的大小以提高速度,因此如果程序大小无关紧要,可能会有所帮助。
答案 1 :(得分:0)
你可以对Asin
使用以下近似值,在我的测试中,它的速度只有Math.Asin
的两倍(32位,如果手动内联更好,在64位以下,它的速度略快于两倍) )它看起来相当准确,但你必须测试准确度是否可以接受。
static double Asin(double x)
{
double x2 = x * x;
double x3 = x2 * x;
const double piover2 = 1.5707963267948966;
const double a = 1.5707288;
const double b = -0.2121144;
const double c = 0.0742610;
const double d = -0.0187293;
return piover2 - Math.Sqrt(1 - x) * (a + b * x + c * x2 + d * x3);[]
}
(当然这是C#,但你可以转换它我确定)
[编辑] 这是VB版本。
Shared Function Asin(ByVal x As Double) As Double
Dim x2 As Double = x * x
Dim x3 As Double = x2 * x
Const piover2 As Double = 1.5707963267948966
Const a As Double = 1.5707288
Const b As Double = -0.2121144
Const c As Double = 0.0742610
Const d As Double = -0.0187293
Return piover2 - Math.Sqrt(1 - x) * (a + b * x + c * x2 + d * x3)
End Function
答案 2 :(得分:-1)
您可以尝试将series expansion实现为您需要的任何精度,并将其与Stochastically建议的查找表(可能是Math.asin
最终计算它的方式)进行比较,并根据所需的精度构建。但是,你似乎不太可能享受到你想要的处理时间减半。
如果计算没有明显依赖于彼此(或者如果依赖关系可以被隔离到不同的批次中),您可能会尝试并行运行它们(无论是在不同的系统上还是使用不同的处理器),但要小心 - - 我在太空物理实验室工作,我们发现当我们在不同的系统上运行测试时,我们所需的精度会产生真的恼人的异常。
(我也必须说,我非常好奇为什么你需要进行数十亿次正弦计算。)