Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 12 Next capture
2021 2022 2023
1 capture
12 Jun 22 - 12 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 Dyonisian · Jun 13, 2018 at 07:07 AM · optimizationloopdelegates

Managing a lot of GameObjects, calling functions on 1000 objects in a loop is very slow - Optimize/ECS/Delegates?

Hi, I basically spawn a 1000ish objects which have a script and either a line or mesh renderer on them. I later try to loop through them to enable those mesh/line renderers. The reason is for creating an effect of seeing them all drawn one by one rather than having them all appear at the same time. However it seems its very slow to access all of these GameObjects and run a function on their scripts. It's in a coroutine because I want to be able to see them appear one by one, not all at once. The cost of the objects, the rendering, and the actual code being accessed does not seem to be a lot - its just that iterating through this list and calling a function on each GameObject seems slow - takes about 10-15 seconds, and this does not reduce a lot if I disable what the functions are actually doing.

Is there an obvious solution I am missing here? If I want to trigger something on a 1000 GameObjects at once, would it better to use something like events or delegates? Is this a use case where ECS would be applicable, and result in a boost?

Thanks

   IEnumerator AnimateNeurons()
     {
         if (!isRendered)
         {
             isTiming = true;
             for(int i=0; i<somas.Length; i++)
             {
                 somas[i].EnableRenderer();
                 //segments = neuron.transform.GetComponentsInChildren<SegmentAnimation>();
                 //Debug.Log("Number of segments - " + segments.Length);
 
                 //foreach (SegmentAnimation seg in segments)
                 //{
                 //    seg.EnableRenderer();
                 //    yield return null;
                 //}
                 yield return null;
             }
             isRendered = true;
         }
         Debug.Log("Finished coroutine, took " + timer);
         yield return null;
     }

There are 302 somas, the function I call just enables individual mesh renderers. There's an inner loop I commented out which enables line renderers on children of the somas - which total to around a 1000. Its commented out because I tried doing that inside the soma scripts instead of in this loop, to see if it helped. But even iterating through 302 somas takes 10-15 seconds. I realize I might be using coroutines incorrectly, so that might be the issue.

Comment
Add comment · Show 6
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 NoDumbQuestion · Jun 13, 2018 at 07:25 AM 2
Share

You need to show us the scripts. In most case your script might not functioning like the way you think

avatar image Dyonisian NoDumbQuestion · Jun 13, 2018 at 08:39 AM 0
Share

I've updated the question with some code and additional explanation. I realize I might be using coroutines incorrectly, which might be causing the issue.

avatar image Harinezumi · Jun 13, 2018 at 07:35 AM 0
Share

Please show the script, especially the loop part. Calling a function 1000 times should not be that performance intensive. Do you call GetComponent() a lot on the loop? Have you profiled what takes long?

avatar image Dyonisian Harinezumi · Jun 13, 2018 at 08:40 AM 0
Share

I've updated the question with some code and additional explanation. I realize I might be using coroutines incorrectly, which might be causing the issue.

I haven't profiled but what I tried is removing the actual content of the function, so its just a loop calling an empty function. That didn't seem to improve the speed at all. Which is why I feel its an issue either with how I'm assu$$anonymous$$g coroutines work or with just looping through too many objects.

avatar image Harinezumi Dyonisian · Jun 13, 2018 at 09:22 AM 1
Share

Thanks for posting the code and adding additional explanation.
The code is running "slow" not because of being sub-optimal, but because after enabling each soma you are telling it to wait for the next frame (due to yield return null;). For ~300 objects at 60 FPS it will take 5 seconds for all of the objects to enable.
But isn't this what you wanted to achieve, make them appear one by one, ins$$anonymous$$d of all of them together? Or you just don't want all of them to appear together, but it is fine of more than one appears? In that case, decide over how much time or how many frames you want the objects to appear, and enable total number / duration objects each frame.

Some code:

 [SerializeField] private int numFramesToAppear = 15; // about 0.25 seconds @ 60 FPS
 
 private IEnumerator AnimateNeurons () {
     isTi$$anonymous$$g = true;
     int numToEnableEachFrame = somas.Length / numFramesToAppear; // I might be off by 1 here, so that not all objects will get enabled; in that case add +1 to numFramesToAppear
     int frameCounter = 0;
     while (frameCounter < numFramesToAppear) {
          int startIndex = frameCounter * numToEnableEachFrame;
          for (int i = startIndex; i < startIndex + numToEnableEachFrame && i < somas.Length; ++i) { somas[i].EnableRenderer(); }
          frameCounter++;
          yield return null;
     }
     Debug.Log("Finished coroutine, took " + timer);
 }


Show more comments

1 Reply

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

Answer by NoDumbQuestion · Jun 13, 2018 at 08:42 AM

The issue is quite simple.

 yield return null;

return null mean wait for next update(). You are waiting every update to Enable render.

Comment
Add comment · Show 4 · 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 Dyonisian · Jun 13, 2018 at 08:57 AM 0
Share

That's a good point, I'll try changing that. $$anonymous$$y assumption was that yield return null would be the fastest way to do this. If ins$$anonymous$$d i had yield return new WaitForSeconds(0.1f), or a smaller value, would that actually be faster and still be non-blocking? Since it's not limited by how often update is being called?

avatar image NoDumbQuestion Dyonisian · Jun 13, 2018 at 09:05 AM 1
Share

It won't make any different.

Don't use couroutine. Use time countdown. How many spawn per seconds?

Call update. Check time delta from last frame. Spawn that many soma based on your spawn value. Then enable them in update. When all enable. Disable that time countdown object.

couroutine will be called in next update() anyway so no need to call wait. The result will be the same

avatar image Dyonisian NoDumbQuestion · Jun 13, 2018 at 09:06 AM 0
Share

You're right, that didn't work. I will try what you've suggested now. I had considered that, but I thought it was better practice/cleaner code to do it in a coroutine. I was thinking of a coroutine as sort of a non-blocking function. Like an extension of update. Is there no way to achieve what I want to do using coroutines? I'm just curious. Thanks

Show more comments

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

94 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 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 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 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 avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image

Related Questions

Speeding up nested for loop of structs and calculations 0 Answers

How do I optimize the "Player Loop"? 2 Answers

Need tips for optimizing main func that loops through thousands of particles 0 Answers

How to play many animations at once without slowdown? 3 Answers

Looping through vector3 list slow 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