I was curious about the impact of several Mathf functions when running an app on iPhone. So I decided to make some measurements on iPhone 5 and iPhone 4. Here are the results.
Setup
Although the really heavy maths in RRRunner is performed within a native code library, there are several locations where calculations are needed. So the goal was just to get an idea of how expensive functions like Mathf.Asin (), quaternion multiplications, … are. Not the pure objective tests known but a practical overview of do’s and dont’s when I have to decide about the costs and which feature to implement in what way.
So I set up a simple test for:
- Mathf functions Asin, Atan2, Sin, SmoothDamp
- Quaternion multiplikation and Slerp
- System.Math Asin, Atan2 and Sin
The code (download here) I used:
// ... Quaternion q1 = Quaternion.Euler (10f, 20f, 30f); Quaternion q2 = Quaternion.Euler (40f, 50f, 60f); Quaternion q = Quaternion.identity; begin = Time.realtimeSinceStartup; for (int i = 1; i < count; i++) { q = q1 * q2; } elapsedMillis = (Time.realtimeSinceStartup - begin) * 1000; Log.Debug (System.String.Format ("{0} {1} elapsed: {2:F3} ms", "Quaternion-Multiplikation", count, elapsedMillis)); // ...
I executed the test for several functions I use pretty often and ran it in a) Unity editor, b) iPhone 4 with iOS 5.1.1 c) iPhone 5 with iOS 6.01. Tests are run in main thread within a game having some native code running in its own thread. So this is not representative but I just wanted to have a rough estimate in a typical situation.
Every method is called 100,000 times per single test and there are 10 tests for each method so that there are 1,000,000 calls in total. As I output the elapsed time in milliseconds, I divided the total through 1,000 in my LibreOffice sheet to get microseconds.
Results
Unity editor player:
Method | Time / [µs] |
Asin | 0.086215 |
Atan2 | 0.082093 |
Math.Asin | 0.068097 |
Math.Atan2 | 0.082449 |
Math.Sin | 0.032553 |
Quaternion-Multiplikation | 0.039977 |
Quaternion-Slerp | 0.149305 |
Sin | 0.047591 |
SmoothDamp | 0.072673 |
iPhone 5
Method | Time / [µs] |
Asin | 0.200728 |
Atan2 | 0.234652 |
Math.Asin | 0.365753 |
Math.Atan2 | 0.199479 |
Math.Sin | 0.205536 |
Quaternion-Multiplikation | 0.209732 |
Quaternion-Slerp | 0.443405 |
Sin | 0.262145 |
SmoothDamp | 0.540069 |
iPhone 4
Method | Time / [µs] |
Asin | 0.910897 |
Atan2 | 1.233786 |
Math.Asin | 1.805528 |
Math.Atan2 | 0.896995 |
Math.Sin | 0.762788 |
Quaternion-Multiplikation | 1.83786 |
Quaternion-Slerp | 1.804771 |
Sin | 1.004631 |
SmoothDamp | 3.447878 |
Comparison
Method | Time / [µs] | ||
Editor | iPhone 5 | IPhone 4 | |
Asin | 0.086215 | 0.200728 | 0.910897 |
Atan2 | 0.082093 | 0.234652 | 1.233786 |
Math.Asin | 0.068097 | 0.365753 | 1.805528 |
Math.Atan2 | 0.082449 | 0.199479 | 0.896995 |
Math.Sin | 0.032553 | 0.205536 | 0.762788 |
Quaternion-Multiplikation | 0.039977 | 0.209732 | 1.83786 |
Quaternion-Slerp | 0.149305 | 0.443405 | 1.804771 |
Sin | 0.047591 | 0.262145 | 1.004631 |
SmoothDamp | 0.072673 | 0.540069 | 3.447878 |
Download all data (LibreOffice Calc)
Side Effects And Possible Improvements
Running in a multi-threaded environment can of course distort the measured times. To get more reliable results it would be better to sum the time of each call but on the other hand rounding effects might have a negative impact then. The same applies to background processes running on the device.
Some of the methods might have caching strategies so that for example 100,000 calls to Asin (0.707f) might be much faster than a version calling Asin with random numbers as parameters. SmoothDamp and Quaternion-Slerp were the only functions in this test, that were called with different parameters like “smoothTime / i” and they are the slowest. But I don’t think that this effect has to be considered as the results are still plausible.
Conclusion
As long as the results are around 1 µs I don’t care about a single call. It’s no surprise to see huge differences between iPhone 4 and iPhone 5 but even on iPhone 4 there is no reason to not use a single SmoothDamp for improving camera tracking.
The difference between Mathf and System.Math calls appears a bit confusing but might be subject to the non-objective measuring environment that was chosen intentionally. Mostly System.Math seems to be the better choice but as Asin shows, this could be wrong and a new Unity version might come up with an improved Mathf version.
nice!!