Boxing & Unboxing: Kẻ thù giấu mặt của hiệu năng Unity
C# Code
using UnityEngine;
using System.Collections.Generic;
using System.Collections; // Namespace của ArrayList
public class BoxingExample : MonoBehaviour
{
void Start()
{
// --- Boxing ---
int i = 123; // Value type trên Stack.
// Boxing xảy ra ở đây: một object được tạo trên Heap để chứa giá trị của 'i'.
// Thao tác này tạo ra rác (garbage).
object o = i;
// --- Unboxing ---
// Unboxing: Lấy giá trị từ object trên Heap về lại Stack.
int j = (int)o;
}
// Cạm bẫy hiệu năng kinh điển trong Unity
void Update()
{
// ---- CÁCH TỆ: Dùng collection không generic (như ArrayList) ----
// ArrayList chứa các 'object', vì vậy mỗi lần Add một value type (như int)
// sẽ gây ra Boxing, tạo ra rác mỗi frame. RẤT TỆ!
ArrayList arrayList = new ArrayList();
arrayList.Add(10); // BOXING!
int value = (int)arrayList[0]; // UNBOXING!
// ---- CÁCH TỐT: Dùng collection generic (như List<T>) ----
// List<int> được thiết kế để làm việc trực tiếp với kiểu 'int'.
// Không có Boxing, không tạo rác. LUÔN DÙNG CÁCH NÀY!
List<int> genericList = new List<int>();
genericList.Add(10); // KHÔNG BOXING!
int value2 = genericList[0]; // KHÔNG UNBOXING!
// Một ví dụ khác: Dùng string.Format với value types
// string s = string.Format("Score: {0}", 100); // Gây Boxing cho số 100
// Cách tốt hơn:
string s_good = "Score: " + 100.ToString(); // ToString() không gây Boxing.
}
}Boxing là quá trình chuyển một Value Type (như int, float) lên Heap bằng cách 'gói' nó trong một object. Unboxing là quá trình ngược lại. Trong Unity, việc này xảy ra âm thầm và thường là nguyên nhân gây ra các vấn đề về Garbage Collection và sụt giảm FPS mà không ai ngờ tới.