目前,我的代码如下所示:
private List<Node> dirtyNodes = new List<Node> dirtyNodes();
public void UpdateDirtyNodes()
{
while(dirtyNodes.Count > 0)
{
Node nodeToUpdate = dirtyNodes[0];
nodeToUpdate.UpdateNode();
dirtyNodes.Remove(nodeToUpdate);
}
}
public void MarkNodeDirty(Node node)
{
if(!dirtyNodes.Contains(node))
{
dirtyNodes.Add(node);
}
}
public void MarkNodeClean(Node node)
{
dirtyNodes.Remove(node);
}
这是代码中性能关键的部分,它比我想要的要慢,因为在大多数情况下 dirtyNodes.Contains
必须迭代整个数组。我想用 HashSet
替换 List
因为它应该更快,但我不知道如何使用 UpdateDirtyNodes() 来实现它
.
困难在于 UpdateNode()
可以随时向 dirtyNodes
添加或删除节点,因此 while 循环有点尴尬。有没有办法从 HashSet 中获取“第一个”值?顺序并不重要,我只需要停留在 while 循环中,直到 dirtyNodes
为空,更新接下来出现的任何节点。
我宁愿避免使用 Linq,因为此代码将成为库的一部分,并且我不想强制它们包含 Linq。
我该怎么做?
最佳答案
事实证明,直接使用枚举器非常简单:
public void UpdateDirtyNodes()
{
while(dirtyNodes.Count > 0)
{
using(HashSet<Node>.Enumerator enumerator = dirtyNodes.GetEnumerator())
{
if(enumerator.MoveNext())
{
Node nodeToUpdate = enumerator.Current;
nodeToUpdate.UpdateNode();
dirtyNodes.Remove(nodeToUpdate);
}
}
}
}
public void MarkNodeDirty(Node node)
{
dirtyNodes.Add(node);
}
我最初尝试过类似的方法,但没有完全理解如何手动使用枚举器,而且它不起作用。
它比 List
快得多(总体帧时间快约 25-50%,具体取决于仅从一项更改开始的情况),所以我非常高兴。 (不要对下面屏幕截图中的 30MB 分配感到 panic - 我正在处理它。)
关于c# - 从 HashSet 获取第一个(或任何)值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/69869124/