Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 13 Next capture
2021 2022 2023
1 capture
13 Jun 22 - 13 Jun 22
sparklines
Close Help
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
avatar image
0
Question by m0nkeybl1tz · Feb 27, 2015 at 08:52 PM · c#optimizationfunctionlerp

Understanding the cost of different functions

So this is something I've never been sure of, but since I have a concrete example right now, I figured I'd run it by you all so I can learn for the future.

Basically, I'm making a submarine game, and the submarine returns to a neutral position if no button is pressed. As it stands right now, I check every frame to see if a button is being pressed, and if it isn't, I Lerp between the current position and the neutral position, like so:

 if (!Input.GetKey (KeyCode.UpArrow) && !Input.GetKey (KeyCode.DownArrow)) {
     currentX = Mathf.Lerp (currentX, 0, Time.deltaTime);
 }

However, this feels wasteful to me, as it will continue to Lerp even when it's returned to a neutral position. I was considering adding an if statement to check to see if it's at a neutral position, something like this:

 if Mathf.Abs (currentX > .01f){
     if (!Input.GetKey (KeyCode.UpArrow) && !Input.GetKey (KeyCode.DownArrow)) {
         currentX = Mathf.Lerp (currentX, 0, Time.deltaTime);
     }
 }

Alternately, I could do it:

 if (!Input.GetKey (KeyCode.UpArrow) && !Input.GetKey (KeyCode.DownArrow)) {
     if Mathf.Abs (currentX > .01f){
         currentX = Mathf.Lerp (currentX, 0, Time.deltaTime);
     }
 }

So I guess my question is, which of these 3 would be the fastest? Thanks!

Adam

Comment
Add comment
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users

2 Replies

· Add your reply
  • Sort: 
avatar image
3
Best Answer

Answer by Jessespike · Feb 27, 2015 at 10:53 PM

The difference is quite insignificant with modern technology. And since the calculation is only executed once per frame and not many times for many objects, you could probably just skip this thought. But since you asked, and I was curious myself, I decided to run a test. Like most technical problems, the answer will be... it depends. Depends on the hardware, what value currentX is, if you're pressing any keys, etc...

To run your own tests, get the profile script here: http://wiki.unity3d.com/index.php/Profiler

Now according to my super-scientific research, the results show that the 3rd method is the fastest on average.

no keys being pressed, currentX being greater than 0.01 for most of the time

  • Method 1 took 0.003008700 seconds to complete over 1000 iterations, averaging 0.000003009 seconds per call

  • Method 2 took 0.001624600 seconds to complete over 1000 iterations, averaging 0.000001625 seconds per call

  • Method 3 took 0.000533800 seconds to complete over 1000 iterations, averaging 0.000000534 seconds per call

Holding up arrow key

  • Method 1 took 0.003370300 seconds to complete over 1000 iterations, averaging 0.000003370 seconds per call

  • Method 2 took 0.002678900 seconds to complete over 1000 iterations, averaging 0.000002679 seconds per call

  • Method 3 took 0.001618500 seconds to complete over 1000 iterations, averaging 0.000001619 seconds per call

Now having said all that, I would personally choose the method that is easiest to read and maintain. Code readability is far superior than micro-optimizations. That doesn't mean I completely disregard performance, but something as trivial as this seems to be a waste of time and energy that could be focused on other tasks, or be optimizing something that would have a noticeable effect on performance.

Here's the test script I used:

 using UnityEngine;

 public class SomeProfileTest : MonoBehaviour {
     
     float currentX = 1000f;
     int iterations = 1000;
     int elapsedIterations = 0;
 
     // Update is called once per frame
     void Update () {
 
         float frameCurrentX = currentX;
 
         Profile.StartProfile("Input Method 1");
             if (!Input.GetKey (KeyCode.UpArrow) && !Input.GetKey (KeyCode.DownArrow)) {
                 currentX = Mathf.Lerp (currentX, 0, Time.deltaTime);
             }
         Profile.EndProfile("Input Method 1");
         currentX = frameCurrentX;
 
         Profile.StartProfile("Input Method 2");
             if (Mathf.Abs (currentX) > .01f){
                 if (!Input.GetKey (KeyCode.UpArrow) && !Input.GetKey (KeyCode.DownArrow)) {
                     currentX = Mathf.Lerp (currentX, 0, Time.deltaTime);
                 }
             }
         Profile.EndProfile("Input Method 2");
         currentX = frameCurrentX;
 
         Profile.StartProfile("Input Method 3");
             if (!Input.GetKey (KeyCode.UpArrow) && !Input.GetKey (KeyCode.DownArrow)) {
                 if (Mathf.Abs (currentX) > .01f){
                     currentX = Mathf.Lerp (currentX, 0, Time.deltaTime);
                 }
             }
         Profile.EndProfile("Input Method 3");
 
 
         elapsedIterations++;
         if (elapsedIterations >= iterations)
         {
             Application.Quit();
             Debug.Break();
         }
     }
     
     void OnApplicationQuit () {
         Profile.PrintResults();
     }
 
     void OnGUI() {
         GUI.Label(new Rect(0f, 0f, 100f, 100f), currentX.ToString());
     }
     
 }
 



Comment
Add comment · Show 1 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image m0nkeybl1tz · Mar 01, 2015 at 09:47 PM 0
Share

Wow, thanks for doing all that. I'll definitely start using that profiler thing, that seems very useful. I guess the time difference seems pretty $$anonymous$$uscule, I just remember in program$$anonymous$$g class in high school, even something as simple as counting took a noticeable amount of time, so I was paranoid that something more complex like calculating averages or absolute values every frame might make a real difference. But apparently not!

avatar image
1

Answer by siaran · Feb 27, 2015 at 10:30 PM

I don't think the difference between those would really be noticable, so I wouldn't bother with trying to figure out the most optimized method. Instead write the code in the way that you think makes the most sense.

If you want to check for a neutral position, then, imo, that's the last one - I also suspect checking Mathf.Abs() takes a little more to check than 2 input booleans and that way lets you get out of the if statment before you check Mathf.Abs() - I'm not sure about that but I would be surprised if it was different.

I don't think checking for it makes any real difference performance-wise though, Lerp should be a fairly cheap method.

In fact, not checking may be the best way performance-wise. I don't know how Lerp compares to (x > Math.Abs), but in cases where you need to Lerp you'll have to evaluate both. If you only very rarely DONT Lerp (wether this is the case depends on your game), constantly checking for a neutral position might be a net decrease in performance.

Not a definitive answer to your question as to what is fastest I suppose, but some things worth considering in any case.

Comment
Add comment · Show 1 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image m0nkeybl1tz · Mar 01, 2015 at 09:45 PM 0
Share

That makes a lot of sense. Thanks for your perspective!

Your answer

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Follow this Question

Answers Answers and Comments

21 People are following this question.

avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image

Related Questions

Multiple Cars not working 1 Answer

Distribute terrain in zones 3 Answers

Use Lerp Position and Slerp Rotation together 0 Answers

[Editor Scripting] Call Function in other GameObjects Editor Script? 0 Answers

3D Grapher - Function input problem 1 Answer


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges