0

我有以下代码行:

SomeDouble= constant1/ ((a * b) * (Math.Asin((c- a) / (a * d)) + constant2))

这两个常数是不同的,并且是在循环中计算出来的,a - d 是每次都会变化的变量。

从表面上看,它的平均速度相当快 0.002 毫秒(26,508,249 次点击为 47,633.588 秒)。我遇到的问题是它会被调用数十亿次,每次运行软件时都会有大约 200 亿次点击。因此,如果我可以将其减少到 0.001 毫秒,那么差异将是巨大的。我知道除法是一个非常缓慢的过程,我希望计算 arcsin 也很慢。如果有人可以建议是否有更快的计算 arcsin 的方法或任何其他有助于加快这行代码的速度,那就太好了。附带说明一下,关于 vb.net 的内置数学函数是否针对速度进行了优化的任何建议都会很棒我注意到 math.sqrt(somevalue) 比 (somevalue)^0.5 快。

先谢谢了!

4

3 回答 3

2

我会做一些测试以确保 Math.Asin 确实是公式中最慢的部分。如果它相对于其他乘法和除法真的很慢,那么您可以尝试为 Math.Asin 实现自己的查找表。换句话说,预先计算数百万个 Math.Asin 值,并将它们编码到您的程序中。这将以您的程序大小换取速度,因此如果程序大小无关紧要,它可能会有所帮助。

于 2013-05-24T18:14:18.627 回答
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
于 2013-05-24T18:29:52.467 回答
-1

您可以尝试将级数扩展实现为您需要的任何精度,并将其与随机建议的查找表(很可能是Math.asin最终计算它的方式)进行比较,以建立所需的精度。但是,您似乎不太可能享受将处理时间减半的情况。

如果计算没有有意义地相互依赖(或者如果依赖关系可以隔离到不同的批次中),您可能会尝试并行运行它们(无论是在不同的系统上还是使用不同的处理器),但要小心——我工作过在一个空间物理实验室,我们发现当我们在不同的系统上运行测试时,我们需要的精度会产生非常烦人的异常。

(我还必须说,我非常好奇为什么需要运行数十亿次反正弦计算。)

于 2013-05-24T22:31:30.623 回答