c# - 从 HashSet 获取第一个(或任何)值

标签 c# hashset

目前,我的代码如下所示:

    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 - 我正在处理它。)

enter image description here

关于c# - 从 HashSet 获取第一个(或任何)值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/69869124/

相关文章:

c# - C# 检查点库

c# - Linq 查询列表包含具有相同顺序的列表

hash - clojure 中的文字哈希集

c# - 异步方法异常的不同行为

c# - Xamarin.Forms MediaManager 从本地存储播放视频

c# - 如何从字节数组(在内存中)运行方法?

java - java.io.File.delete() 的异常返回值被忽略

javascript - 与 C# HashSet 等效的 JavaScript 是什么?

java - Java 中删除重复项的最快、最有效的方法

java - List 抛出 ConcurrentModificationException 但 set 不抛出 ConcurrentModificationException?