Dlaczego zawsze powinienem rozważyć tworzenie i używanie pul obiektów zamiast tworzenia nowego obiektu w locie?

25

Przeczytałem o tym schemacie kilka razy (z perspektywy najlepszych praktyk):

Alokacja pamięci : Zamiast tworzenia nowego obiektu w locie zawsze należy rozważyć utworzenie i użycie pul obiektów. Pomoże to zmniejszyć fragmentację pamięci i sprawi, że moduł czyszczenia pamięci będzie działał mniej.

Nie wiem jednak, co to właściwie znaczy. Jak mogę to zaimplementować?

Na przykład mogę utworzyć instancję GameObjectprzy użyciu Instantiatemetody Unity?

Instantiate(prefab, new Vector3(2.0F, 0, 0), Quaternion.identity);

Czy to użycie jest odradzane? Co jeszcze może to znaczyć?

Muhammad Faizan Khan
źródło
Dzięki Hellium, nie oglądałem podanego filmu (zbyt dużego), ale tekst naprawdę pomaga mi zrozumieć „Akt tworzenia i niszczenia jest nieefektywny i może spowolnić twoje projekty”
Muhammad Faizan Khan
1
Pamiętaj, że chociaż ta rada jest powszechna, nie jest to bezwzględny wymóg dla każdej gry. Zwłaszcza jeśli tworzysz małą / krótką grę komputerową, przesyłanie dżemu lub prototyp, nie musisz rezygnować z implementacji puli. W moich testach nasiąkania Unity wytrzymuje nawet masowe odradzanie i niszczenie lepiej, niż nam to przypisuje. ;) Ale rozważ rozważenie puli, jeśli tworzysz długą grę, w której nie chcesz, aby śmieci gromadziły się i powodowały zacinanie się, gdy są zbierane później, lub jeśli atakujesz platformy mobilne, na których bardziej odczuwalny jest wpływ na wydajność.
DMGregory
Dzięki @DMGregory Masz rację. Twój wkład jest zawsze cenny. Nie powinniśmy się martwić o pule obiektów w małych grach, ponieważ będzie to wymagało dodatkowej pracy przy kodowaniu.
Muhammad Faizan Khan
1
Jest to bardzo powszechny wzorzec, ale należy go temperować zgodnie z regułą: „Najpierw profil, a następnie optymalizacja”. Łatwo jest zoptymalizować rzeczy, które nie mają znaczenia.
Cort Ammon - Przywróć Monikę

Odpowiedzi:

41

Jeśli planujesz utworzyć wiele instancji tego samego prefabrykatu, zdecydowanie powinieneś pomyśleć o użyciu puli obiektów. Wywołanie funkcji tworzenia instancji Unity jest jedną z najbardziej obciążających metod, jakie możesz wykonać.

Pula obiektów polega na tworzeniu instancji prefabrykatów przed ich użyciem. Są dezaktywowane natychmiast po utworzeniu instancji i reaktywowane tylko wtedy, gdy są potrzebne. Wprawdzie zwiększa to wykorzystanie pamięci, ale pozwala uniknąć nakładania się procesora na proces tworzenia się podczas gry.

Na przykład obecnie pracuję nad grą w piekło z kulami, która wymaga odrodzenia setek pocisków w czasie wykonywania. Początkowo próbowałem stworzyć grę bez łączenia obiektów, ale skończyło się to katastrofą (mniej niż 2 fps). Teraz zbieram 500 kul przed rozpoczęciem gry, a gra działa zadziwiająco szybko (200 fps).

Istnieją sytuacje, w których nie można użyć puli obiektów. Na przykład, jeśli masz grę, w której dane wejściowe gracza decydują o tym, który prefabrykat zostanie spawnowany, możesz nie mieć innego wyboru, jak użyć zwykłego połączenia natychmiastowego. Pula obiektów jest możliwa tylko wtedy, gdy wiesz z góry, jakie obiekty będą potrzebne.

Samouczek Sebastiana Lague'a na YouTube to świetne źródło informacji na temat łączenia obiektów: https://youtu.be/LhqP3EghQ-Q

Kevin H.
źródło
„Tworzenie instancji i niszczenie jest nieefektywne i może spowolnić twoje projekty”. to jest powód? Oznacza to, że musimy zakodować nieco więcej (na przykład aktywować dezaktywację lub ponownie ustawić pozycję pocisku, abyśmy mogli ponownie wystrzelić)
Muhammad Faizan Khan
12
Warto wspomnieć o alokacji i wyrzucaniu elementów bezużytecznych jako głównych elementach kosztu powtarzalnej instancji i niszczenia. Wygeneruj wystarczającą ilość śmieci, a ostatecznie cała gra musi poczekać, aż śmieciarz to wszystko zmieci. ;)
DMGregory
3
@corsiKa byłaby to optymalizacja z lat 80-tych. Unity może po prostu dezaktywować dane prefabrykaty, powodując, że ich systemy go zignorują.
congusbongus,
2
„Na przykład, jeśli masz grę, w której dane wejściowe gracza decydują o tym, który prefabrykat jest spawnowany, możesz nie mieć innego wyboru, jak użyć zwykłego połączenia natychmiastowego.” - Nie całkiem. Możesz łatwo mieć wiele pul obiektów dla różnych prefabrykatów przypisanych do pożądanych rozmiarów podczas uruchamiania (lub ładowania sceny). Lub, jeśli ktoś chce to zrobić, pula obiektów, która przechowuje wiele typów prefabrykatów, może również działać.
Ethan Bierlein,
1
@DMGregory W typowym środowisku GC alokacja stanowi większość kosztów; w typowym środowisku innym niż GC alokacja stanowi większość kosztów. Łączenie obiektów działa świetnie dla obu, w rzeczywistości są to po prostu dwie strony tej samej monety w przeważającej części. W skrajnym przypadku stare gry były pisane ze wszystkimi obiektami „przydzielanymi” od samego początku - bardzo mało lub brak przydzielania pamięci podczas uruchamiania gry. Tak naprawdę nie użyłeś niczego, co nie zostało w jakiś sposób „połączone”. Ponieważ Unity korzysta z wielu „metadanych” w czasie rzeczywistym, pula może być bardzo pomocna - choć jej implementacja może być trudniejsza.
Luaan,