Home > OS >  Curious case of efficiency of equation algorithm, why are more operations faster?
Curious case of efficiency of equation algorithm, why are more operations faster?

Time:01-16

I lately wrote a bit that shall smooth out the extends of a 0-1 range. Out of curiousity I measured the performance of two possibilities to acchieve the same end result. What came out is that this:

_ = (Mathf.Sin(-1.57079633f (time * 3.14159265f)) 1) * 0.5f; // Sin 4o

faster than this

_ = Mathf.Cos(time * 3.14159265f) * -0.5f 0.5f; // Cos 3o

even though the former has more operations? And it's not faster by just some tiny bit, it's approximately 31% faster. For time t a constant of 0.5f was used.

There's no difference in using Sin or Cos for either, I did test for that in case the algorithm behind those functions would be the cause. Since Mathf is a Unity thing i tested it using System.Math. as well to make sure this isn't the cause, the results are roughly the same exept that System.Math. is overall a tiny bit slower since it calculates a double that then has to be cast to a float (Single).

Is Someone able to enlighten me why this is the case? I'd be interessted in undestanding why this is.

Addendum: Testing code

var sw = new System.Diagnostics.Stopwatch();
sw.Start();
for (int i = 0; i < 500000; i  )
{
    _ = (Mathf.Sin(-1.57079633f   (time * 3.14159265f))   1) * 0.5f; // Sin   4o
}
sw.Stop();
print($"Sin calc time = {sw.ElapsedTicks * 0.0001f}ms ({sw.ElapsedMilliseconds}ms)");
sw.Restart();
for (int i = 0; i < 500000; i  )
{
    _ = Mathf.Cos(time * 3.14159265f) * -0.5f   0.5f; // Cos   3o
}
sw.Stop();
print($"Cos calc time = {sw.ElapsedTicks * 0.0001f}ms ({sw.ElapsedMilliseconds}ms)");

CodePudding user response:

When using a value of 0.5 for time, the call to Math.Sin() ends up calling Math.Sin(0) - and I suspect that the implementation of Math.Sin() has an optimisation for that case that just returns 0.

The value passed to Math.Cos(), however, will be ~1.5707963705062866, and it's likely that this will NOT have a similar optimisation.

The fact that your time value was const also means that the compiler can pre-calculate the values passed to Math.Sin() and Math.Cos() which means that it doesn't matter if the calculation for Math.Sin() contains more operations, since they will not be performed at run-time.

  • Related