Making While Loop More Efficient

Whenever my While Loop is called and there are many iterations of ‘totalEggs’ which need to be looked at, my project becomes sluggish and I would appreciate some help on knowing how to speed the process up.

I’m making a Chicken Coop Class, to produce eggs and chicks (some becoming hens, which lay even more eggs, some becoming a food source).

    void HatchEggs()
    {
        //A fraction of Eggs must hatch and become newChickens, newHens or perish
        int totalEggs = egg;

        while(totalEggs > 0)
        {
            int outcome = Random.Range(0, 100);
            if(outcome < 65)
            {
                //The egg did not hatch and has was disgarded
                egg = egg - 1;
                Debug.Log("Egg lost");
                totalEggs--;
            }
            if(outcome >= 65 && outcome < 99)
            {
                //The egg hatched into a poultry chick
                egg = egg - 1;
                newChickens = newChickens + 1;
                Debug.Log("Chicken was born");
                totalEggs--;
            }
            if(outcome >= 99)
            {
                if(hen < 10)
                {
                    //The egg hatched into a hen chick
                    egg = egg - 1;
                    newHens = newHens + 1;
                    Debug.Log("Hen was born");
                    totalEggs--;
                }
                else
                {
                    //There are enough hens in the Coop
                    egg = egg - 1;
                    Debug.Log("Amount of Adult Hen has already been reached");
                    totalEggs--;
                }
            }
        }
    }

I have capped the number of hens to 10 and the function is called every 30 days, a hen lays 1 egg a day. This means that this While Loop can have 300 eggs, the player can also create more Chicken Coops, if they so desire. With the sheer amount of while loops everything slows drastically in some situations.

Is there a fix to make While Loops less expensive, or would you suggest that I use another means of each egg having a random chance of hatching/not hatching?

Thanks in advance.

there’s some code compression you can do to reduce the number of lines… but I’m not seeing anything in there that would be particularly taxing.

As far as the “while” loop is concerned it’s effectively the same as a for loop (most loops can be written synonymously)

int i = 300;
while(i>0)
{
    // stuff
    i--
)

for(int i=300; i>0;i--)
{
    // stuff
}

etc.

Have you run the profiler to check that it is this particular function that is causing the performance drop?

edit: although, Debug.Log does have quite a bit of overhead from the stack trace it performs for each call and this function would use them a fair bit… I think the alternative is “System.Console.WriteLine()”

1 Like

Debug.Log is about the most expensive function to call in all of Unity, as it includes the entire call stack. Remove those, and check the result. Come back if it’s still slow.

3 Likes

If you want to remove a while loop then use a table filled up with data ( usually at the start of the game) and later use that data.
Table should not be too big.

This would be very hard but you can try it :smile:

or better in your code you don’t have to use a while loop at all…since you are only increasing / decreasing variables by certain amount.

1 Like

Wow, thanks for the help guys :smile:
I have removed the Debug.Log parts and everything runs smoothly. Almost all functions in my project use Debug.Log, now I think I’ll go around deleting them all.

1 Like

Yeah, Logs are there to debug something quickly, and then be removed again. They’re one of the best tools for figuring out what your code is doing, fast, but they’re not meant to stick around.

Debug.LogWarning and Debug.LogError are great to put in places where you don’t expect your code to reach, so you get notified if something strange’s happening.

1 Like

Debug.Logs are brilliant for debugging… Sometimes you might want to call on these at a later date when you’re making changes. So sometimes you might want to only have them working when you’ve clicked ‘Development Build’ in the Build Settings. In which case you can do this for each Debug.Log call.

if(Debug.isDebugBuild)
            {
                Debug.Log("log something");
            }

if you want to be super safe you can put them in a preprocessor command, which removes the code completely from a build that isn’t in the Unity Editor, like this:

            #if UNITY_EDITOR
            if(Debug.isDebugBuild)
            {
                Debug.Log("log something");
            }
            #endif

Hello,

There is one more tiny optimization you could do that would be worth doing (In my opinion). Your if statements are all IF statements, when you should have IF/Else IF/Else. By having all IF’s you are checking the second and third condition for no reason, if the first condition is true.

Your logic should be:

if(condition) {
// Code
}else if(condition) {
// Code
}else if(condition) {
// Code
}else {
// Code
}

Or I believe you could “break” from the while loop after a condition is matched, but I would do the prior rather than the latter.

Have a great day!

1 Like