2016-12-01 99 views
-3

我需要在我的项目中很多次计算ASin。在C#中需要很多时间。快速ArcSin实现或在c近似#

我用Math.Asin()从系统命名空间

的问题是,有没有什么办法来实现ASIN函数在C#中更快。

任何逼近算法或其他可以工作得更快的实现?

+1

如果一个近似的答案对你来说足够好,那么你应该考虑预先计算一个查找表。您可以使用尽可能多的条目来获得所需的准确性。 – RogerN

+0

我不能使用太多额外的内存,但仍然需要一个很好的近似值。所以预先计算对我来说不起作用。 – Nikita

+0

如果没有其他的方法来实现asin,那么我需要近似函数,但我仍然找不到合适的 – Nikita

回答

1

经过评论和测试基准的一些辩论后,很明显,我在下面给出的解决方案并没有真正改进System.Math.Asin()的性能。事实上,这两个调用几乎可以忽略不计,对于任何应用程序都不应该是一个巨大的影响。如果您遇到性能问题,您的原因可能是以下原因之一:

  1. 您的arcsin调用实际上并不是瓶颈。您需要对您的应用程序进行配置以确定确定的瓶颈。不成熟的优化是一个常见的错误,可能会导致大量浪费时间。
  2. 您正在调用该函数的次数太多。您可能有多次调用某个函数的正当理由,但这些调用很可能会作为更高级别进行优化。可能的解决方案是使用并行呼叫或更改您的操作顺序以减少呼叫。如果你打电话像y = sin(x); z = asin(y),那么你正在进行额外的不必要的电话。这是一个微不足道的例子,但是更复杂的计算可以在数学上产生类似的效果。
  3. 你在某处不应该调用函数。例如,如果您尝试在GUI或渲染线程中进行计算,您将遇到性能问题并且缺乏响应能力。这是一个常见的设计错误,应该注意的是,计算不应该在GUI线程中完成。
  4. 您的用例不可行。如果您正在进行实时数据转换和可视化等操作,那么您可以实时处理多少数据。这取决于硬件,除了将计算卸载到具有更多处理能力的地方外,没有什么可以完成的。像这样的情况是云计算可以派上用场的地方。

这些问题的提出,下面的解决方案仍然是在C#中优化的有效途径。请注意,在对应用程序进行分析之前不应该进行优化,以便您确实知道瓶颈是您认为的瓶颈。请注意,这不是唯一的优化路线。诸如并行处理或选择不同算法等路径也是有效的。


不同的解决方案的一点,但你可以尝试用类似的答案this question加载C标准库。 Windows上的C标准库是msvcrt.dll,应该包含一个函数asin

[DllImport("msvcrt.dll", EntryPoint="asin", 
ExactSpelling=false, CharSet=CharSet.Unicode, 
SetLastError=true)] 
static extern double asin(double radians); 

//calling the function 
static void Main() 
{ 
    double x = asin(0); 
} 

如果这仍然不够快,你可以写一个快速ASIN算法C.有this question,这与你相似。您也可以创建一个更快的平方根函数以用于此解决方案。

根据你需要它的准确程度,如果你要有一个接近0的角度,你也可以做一个泰勒级数近似。你也可以将角度移到接近零,但这需要一个有点诡计。

+0

为什么软链接过程比CLI调用本质上相同的代码更快? – LutzL

+0

我的假设是'System.Math.Asin()'被.NET运行时而不是机器级解释。如果是这种情况,C版本应该更快一些。如果不是,他们应该大致相同。唯一可以肯定的方法是基准。如果性能相同,则C中的自定义实现应该比C#中的相同实现更快。由于OP似乎想要比大多数情况下需要的更多性能,将一些计算移植到C应该能够排除一些额外的性能。 – danielunderwood

+0

我相信它可能在CLI运行时调用asin像其他调用IEEE 754定义的数学函数是硬编码的,应该没有进一步解释的子例程,除了可能的参数检查。 – LutzL