众所周知,如果我们将值类型变量与null进行比较,则会导致GC分配装箱的原因:
{
public class TestGeneric<T>{
public static bool TestGC(T key)
{
return key == null;
}
}
TestGeneric<int>.TestGC(10);
}
但是,我发现LinkedList(System.Collections.Generic(的Find(T value(方法使用了相同的代码,例如
public LinkedListNode<T> Find(T value)
{
if (value != null)
{
//....
}
}
但召唤喜欢
//LinkedList<int> list;
list.Find(10);
不会导致任何 GC 分配。
我对此感到非常困惑。有人有想法吗?请帮忙。非常感谢。
====
================测试环境:Unity 2018,Unity Profiler(深度配置文件启用(.Net 版本:4.0
这是我的测试代码。
public class TestGeneric<T> {
public static bool TestGC(T key)
{
return key == null;
}
}
public class LinkedListTest : MonoBehaviour
{
LinkedList<int> list = new LinkedList<int>();
void Start()
{
for (int i = 0; i < 10; ++i)
{
list.AddLast(i);
}
}
void Update()
{
for (int i = 0; i < 10; ++i)
{
TestGeneric<int>.TestGC(10);
}
for (int i = 0; i < 10; ++i)
{
list.Find(100);
}
}
}
统一性能分析器显示
TestGC 方法导致每帧分配 200 字节 GC
。列表。查找方法导致每帧分配 0 字节 GC
。似乎LinkedList<T>.Find
(https://referencesource.microsoft.com/#System/compmod/system/collections/generic/linkedlist.cs,74e4e6394382badc,references(
使用EqualityComparer<T>
来比较值,而值又使用IEquatable<T>.Equals(T)
(https://learn.microsoft.com/en-us/dotnet/api/system.iequatable-1.equals?view=netframework-4.8(
哪
当调用 Equals 方法并且另一个参数是 T 类型的强类型对象时(如果 other 不是 T 类型,则调用基 Object.Equals(Object( 方法。在这两种方法中,IEquatable.Equals提供了稍微好一点的性能。
由于您正在比较 int 并且它们是相同的类型,因此不会发生装箱,因为未调用 Object.Equals。