C# c语言中的快速arcin实现或近似

C# c语言中的快速arcin实现或近似,c#,math,C#,Math,我需要在我的项目中计算很多次。在C语言中,它需要很多时间 我使用系统名称空间中的Math.Asin 问题是有没有办法在C中更快地实现Asin函数 任何可以更快工作的近似算法或其他实现?在评论和测试基准中进行了一些讨论之后,很明显,我下面给出的解决方案不会真正改善System.Math.Asin的性能。事实上,这两个调用几乎可以忽略不计,对任何应用程序都不会有太大影响。如果遇到性能问题,可能是以下原因之一: 您的arcsin呼叫实际上并不是瓶颈。您需要分析应用程序以确定瓶颈。过早优化是一种常见的错

我需要在我的项目中计算很多次。在C语言中,它需要很多时间

我使用系统名称空间中的Math.Asin

问题是有没有办法在C中更快地实现Asin函数


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

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

您的arcsin呼叫实际上并不是瓶颈。您需要分析应用程序以确定瓶颈。过早优化是一种常见的错误,会导致大量时间浪费。 您调用该函数的次数太多。您可能有充分的理由多次调用函数,但这些调用很可能可以作为更高级别进行优化。可能的解决方案是使用并行调用或更改操作顺序以减少调用。如果你调用的是y=sinx;z=阿西尼,那么你就在打额外的不必要的电话。这是一个微不足道的例子,但许多更复杂的计算可以在数学上产生类似的效果。 您正在调用不应该调用的函数。例如,如果您试图在GUI或渲染线程中进行计算,您将遇到性能问题,并且缺乏响应能力。这是一个常见的设计错误,应该注意的是,计算不应该在GUI线程中完成。 您的用例不可行。如果您正在进行实时数据转换和可视化,那么您可以实时处理的数据量是有上限的。这取决于硬件,除了将计算转移到处理能力更强的地方之外,没有什么可以做的。在这种情况下,云计算可以派上用场。 尽管提出了这些观点,但下面的解决方案仍然是C语言中实现优化的有效途径。请注意,在分析应用程序之前,不应进行优化,以便您真正知道瓶颈在您认为的地方。请注意,这不是优化的唯一途径。并行处理或选择不同算法等路径也是有效的

有点不同的解决方案,但您可以尝试加载C标准库,其中包含类似于的答案。Windows上的C标准库为msvcrt.dll,应包含函数asin:

如果这仍然不够快,您可以用C编写一个快速asin算法。您还可以创建一个更快的平方根函数,以便在该解决方案中使用


根据需要的精度,如果角度接近0,也可以进行泰勒级数近似。你也可以把角度移到接近零,但是这需要更多的诡计。

如果一个近似的答案对你来说足够好,那么你应该考虑预先计算一个查找表。您可以根据需要使用任意多的条目以获得所需的精度。我不能使用太多的额外内存,但仍然需要一个良好的近似值。所以预计算对我来说不起作用。如果没有其他方法来实现asin,那么我需要近似函数,但我仍然找不到合适的方法是asin真的是瓶颈还是需要数组,在数组中安全的C代码由于不断的范围检查而变慢?将代码中缓慢的部分标记为不安全部分是否有助于避免范围检查asinx本质上是atan2x,sqrt1-x*x,其中atan2和sqrt通常由FPU处理,必须非常小心选择,因为它们很容易超过操作计数。您是否实际分析了代码?为什么软链接过程要比对基本相同代码的CLI调用快?我的假设是System.Math.Asin是由.NET运行时而不是在机器级别进行解释的。如果是这种情况,C版本应该快一点。如果不是,它们应该是相同的。唯一确定的方法是基准测试。如果性能相同,C中的定制实现应该比C中的相同实现更快。因为OP似乎想要比大多数情况下需要的性能更高,将一些计算移植到C应该能够挤出一点额外的性能。我相信,与对IEEE 754定义的数学函数的其他调用一样,对asin的CLI运行时调用可能是硬编码的,不应该有进一步的解释子程序,除了可能的论点检查。我把这两个案例放在一起,试图对它们进行基准测试。由此,两种方法得出的结果几乎相同。但我很高兴
除了一些异常值之外,我还看到每次调用都有0或1个勾号,这让我怀疑它的计时是否正确。我原以为这可能是编译器的优化,但我已将这些点保存到一个文件中,并将其读回,以尝试去除编译器预先计算的任何值。如果结果是正确的,我认为OP应该考虑他是否有一个问题。我仍然认为,如果这真的是缓慢的部分,那么有一些环叉=0;K
[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);
}