Mengapa saya harus selalu mempertimbangkan membuat dan menggunakan kumpulan objek alih-alih membuat instance objek baru dengan cepat?

25

Saya telah membaca tentang pola ini beberapa kali (dari perspektif praktik terbaik):

Alokasi Memori : Alih-alih membuat instance objek baru dengan cepat, selalu pertimbangkan untuk membuat dan menggunakan kumpulan objek. Ini akan membantu mengurangi fragmentasi memori dan membuat pengumpul sampah bekerja lebih sedikit.

Namun, saya tidak tahu apa artinya itu sebenarnya. Bagaimana saya bisa menerapkannya?

Sebagai contoh, saya dapat instantiate GameObjectmenggunakan Instantiatemetode Unity?

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

Apakah penggunaan ini tidak disarankan? Apa lagi artinya?

Muhammad Faizan Khan
sumber
Terima kasih Hellium, saya tidak menonton video yang diberikan (terlalu besar) tetapi teks ini benar-benar membantu saya untuk memahami "Tindakan instantiating dan menghancurkan tidak efisien dan dapat memperlambat proyek Anda"
Muhammad Faizan Khan
1
Perhatikan bahwa sementara saran ini umum, itu bukan persyaratan mutlak untuk setiap game. Terutama jika Anda membuat game desktop kecil / pendek, pengiriman selai, atau prototipe, Anda tidak perlu keluar dari cara Anda untuk menerapkan pooling. Dalam tes rendam saya, Unity bertahan hingga pemijahan besar & kehancuran lebih baik dari yang kami berikan. ;) Tetapi pertimbangkan untuk mengumpulkan jika Anda membuat permainan yang panjang di mana Anda tidak ingin sampah menumpuk dan menyebabkan gagap ketika dikumpulkan nanti, atau jika Anda menargetkan platform seluler di mana dampak kinerja terasa lebih tajam.
DMGregory
Terima kasih @DMGregory Anda benar. input Anda selalu berharga. Kami tidak perlu khawatir tentang pengumpulan objek dalam game kecil karena akan membutuhkan kerja ekstra dalam pengkodean.
Muhammad Faizan Khan
1
Ini adalah pola yang sangat umum, tetapi pastikan untuk mengatasinya dengan aturan: "Profil dulu, lalu optimalkan." Mudah untuk mengoptimalkan hal-hal yang tidak penting.
Cort Ammon - Reinstate Monica

Jawaban:

41

Jika Anda berencana untuk instantiate banyak instance dari cetakan yang sama, Anda pasti harus berpikir tentang menggunakan pengumpulan objek. Memanggil fungsi Instantiate Unity adalah salah satu metode panggilan paling berat yang bisa Anda lakukan.

Pengumpulan objek adalah saat Anda membuat cetakan awal sebelum digunakan. Mereka dinonaktifkan segera setelah instantiasi dan diaktifkan kembali hanya ketika mereka dibutuhkan. Meskipun hal ini meningkatkan penggunaan memori, ia menghindari overhead CPU instantiating selama bermain game.

Sebagai contoh, saya saat ini sedang mengerjakan permainan peluru neraka yang membutuhkan ratusan peluru untuk muncul pada saat runtime. Saya awalnya mencoba membuat permainan tanpa pengumpulan objek tetapi akhirnya menjadi bencana (kurang dari 2 fps). Sekarang, saya mengumpulkan 500 peluru sebelum pertandingan dimulai dan permainan berjalan sangat cepat (200 fps).

Ada situasi di mana pengumpulan objek tidak dapat digunakan. Misalnya, jika Anda memiliki permainan di mana input pemain menentukan prefab yang dihasilkan, maka Anda mungkin tidak punya pilihan selain menggunakan panggilan Instantiate yang normal. Pengumpulan objek hanya mungkin jika Anda tahu sebelumnya benda apa yang akan dibutuhkan.

Tutorial YouTube Sebastian Lague adalah sumber yang bagus untuk belajar tentang pengumpulan objek: https://youtu.be/LhqP3EghQ-Q

Kevin H.
sumber
"Tindakan instantiasi dan penghancuran tidak efisien dan dapat memperlambat proyek Anda". ini alasannya Jadi itu berarti kita harus sedikit lebih banyak kode (seperti mengaktifkan deaktif, atau mengatur posisi peluru lagi sehingga kita dapat menembak lagi)
Muhammad Faizan Khan
12
Mungkin perlu menyebutkan alokasi dan pengumpulan sampah sebagai kontributor utama untuk biaya instantiasi & penghancuran berulang. Hasilkan sampah yang cukup dan akhirnya seluruh permainan harus menunggu pengumpul sampah untuk menyapu semuanya. ;)
DMGregory
3
@corsiKa yang akan menjadi optimasi era 80-an. Persatuan dapat menonaktifkan prefab yang dipermasalahkan, membuat sistemnya mengabaikannya.
congusbongus
2
"Misalnya, jika Anda memiliki permainan di mana input pemain menentukan prefab yang muncul, maka Anda mungkin tidak punya pilihan selain menggunakan panggilan Instantiate yang normal." - Tidak juga. Anda dapat dengan mudah memiliki beberapa kumpulan objek untuk prefab berbeda yang dialokasikan ke ukuran yang diinginkan saat startup (atau pemuatan adegan). Atau, jika seseorang ingin membuatnya, kumpulan objek yang menyimpan beberapa jenis cetakan mungkin juga berfungsi.
Ethan Bierlein
1
@DMGregory Dalam lingkungan GC yang umum, de-alokasi adalah sebagian besar biaya; dalam lingkungan non-GC yang khas, alokasi adalah sebagian besar biaya. Pengumpulan objek sangat bagus untuk keduanya, mereka sebenarnya hanya dua sisi dari koin yang sama untuk sebagian besar. Dalam kasus ekstrem, game-game lama dulu ditulis dengan semua objek "dialokasikan" dari awal - sangat sedikit atau tidak ada memori de / alokasi saat game berjalan. Anda tidak benar-benar menggunakan sesuatu yang tidak "dikumpulkan" dengan cara tertentu. Karena Unity menggunakan banyak "metadata" waktu-nyata, penggabungan dapat sedikit membantu - meskipun juga bisa lebih sulit untuk diterapkan.
Luaan