我有一个通用字典,由一个结构体作为键和一个类引用作为值组成。
我通过坐标检索渲染器的引用,并进行以下更改:
每次使用它都会产生0.8KB的垃圾。这是默认行为吗?我认为查找字典应该是最高效的操作之一。由于我正在为移动平台工作,而且这是一个关键系统,所以我需要找到一种解决方法。
有什么想法可能是我的问题或如何获得无需分配的查找?
更多测试后编辑:
使用int作为键而不是我的自定义结构按预期工作。没有分配,没有问题,我认为使用ID作为键不是奇怪的事情。然而,对于我的游戏,我想将与网格中特定瓦片相关联的渲染器存储在一个网格中,这实际上不需要任何类型的对象,因为我只关心网格位置。因此,我认为IntVector2可能是一个实用的标识符,但如果必须,我可以绕过它。
当使用我的结构时,我会生成垃圾,我使用Unity3D Profiler进行测量。它在Dictionary_get_item中报告了0.8KB,特别是DefaultComparer.Equals()。显然,这是一个装箱/取消装箱问题,但即使我实现了我的自定义重写,它仍然会生成垃圾,只比以前少一点。
我的基本结构实现:
“接受答案后编辑:”
“当在通用字典中使用时,我的结构体的无分配版本。”
字典类使用IEquatable接口而不是对象重写Equals方法,这就是为什么我的第一个实现在搜索键时每次检查相等性都会将其中一个值装箱的原因。
Dictionary<IntVector2, SpriteRenderer> tileRendererMap;
我通过坐标检索渲染器的引用,并进行以下更改:
tileRendererMap[tileCoord].color = Color.cyan;
每次使用它都会产生0.8KB的垃圾。这是默认行为吗?我认为查找字典应该是最高效的操作之一。由于我正在为移动平台工作,而且这是一个关键系统,所以我需要找到一种解决方法。
有什么想法可能是我的问题或如何获得无需分配的查找?
更多测试后编辑:
使用int作为键而不是我的自定义结构按预期工作。没有分配,没有问题,我认为使用ID作为键不是奇怪的事情。然而,对于我的游戏,我想将与网格中特定瓦片相关联的渲染器存储在一个网格中,这实际上不需要任何类型的对象,因为我只关心网格位置。因此,我认为IntVector2可能是一个实用的标识符,但如果必须,我可以绕过它。
当使用我的结构时,我会生成垃圾,我使用Unity3D Profiler进行测量。它在Dictionary_get_item中报告了0.8KB,特别是DefaultComparer.Equals()。显然,这是一个装箱/取消装箱问题,但即使我实现了我的自定义重写,它仍然会生成垃圾,只比以前少一点。
我的基本结构实现:
public struct IntVector2
{
public int x, y;
public override bool Equals(object obj)
{
if (obj == null || obj is IntVector2 == false)
return false;
var data = (IntVector2)obj;
return x == data.x && y == data.y;
}
public override int GetHashCode()
{
return x.GetHashCode() ^ y.GetHashCode();
}
}
“接受答案后编辑:”
“当在通用字典中使用时,我的结构体的无分配版本。”
public struct IntVector2 : IEquatable<IntVector2>
{
public int x;
public int y;
public IntVector2(int x, int y)
{
this.x = x;
this.y = y;
}
public bool Equals(IntVector2 other)
{
return x == other.x && y == other.y;
}
}
字典类使用IEquatable接口而不是对象重写Equals方法,这就是为什么我的第一个实现在搜索键时每次检查相等性都会将其中一个值装箱的原因。