After some debate in the comments and a benchmark for testing, it is apparent that the solution I have given below isn't really going to improve on the performance of System.Math.Asin()
. In fact, both of the calls are nearly negligible and shouldn't be a huge impact for any application. If you are running into performance issues, your cause is likely one of the following:
- Your arcsin call isn't actually the bottleneck. You need to profile your application to determine the bottleneck for sure. Premature optimization is a common mistake and can lead to a lot of wasted time.
- You're calling the function too many times. You may have a valid reason for calling a function many times, but the calls are likely able to be optimized as a higher level. Possible solutions would be to use parallel calls or to change your order of operations to reduce calls. If you're calling something like
y = sin(x); z = asin(y)
, then you're making extra unnecessary calls. That is a trivial example, but many more complicated computations can have similar effects mathematically.
- You're calling the function somewhere you shouldn't. For example, if you're trying to do computations in a GUI or rendering thread, you're going to run into performance issues and have a lack of responsiveness. This is a common design mistake and it should be noted that computations should not be done in a GUI thread.
- Your use case isn't feasible. If you're doing something like live data transformation and visualization, then there's an upper limit on how much data you can process in real-time. This is dependent on the hardware and there isn't much that can be done other than offloading the computations to somewhere with more processing power. A case like this is where cloud computing can come in handy.
Those points being made, the solution below is still a valid path towards optimization in C#. Do note that optimization should not be done until profiling an application so you actually know that the bottleneck is where you think it is. Note that this isn't the only route to optimization. Paths such as parallel processing or choosing different algorithms are also valid.
A bit of a different solution, but you can try to load the C standard library with something like the answer to this question. The C standard library on Windows is msvcrt.dll
and should contain a function 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);
}
If this still isn't fast enough, you could write a fast asin algorithm in C. There's this question, which is similar to yours. You could also create a faster square root function to be used in this solution as well.
Depending on how accurate you need it, you could also do a Taylor series approximation if you're going to have an angle close to 0. You could also shift the angle to be close to zero, but that would need a bit more trickery.