无需引入Linq如何从HashSet中获取任意元素优化脏节点更新性能
实现方案
// 替换List为HashSet作为底层存储 private HashSet<Node> dirtyNodes = new HashSet<Node>(); public void UpdateDirtyNodes() { while (dirtyNodes.Count > 0) { // 不依赖LINQ,直接通过枚举器获取任意一个待更新节点 using var enumerator = dirtyNodes.GetEnumerator(); enumerator.MoveNext(); Node nodeToUpdate = enumerator.Current; nodeToUpdate.UpdateNode(); dirtyNodes.Remove(nodeToUpdate); } } // 以下两个方法无需修改逻辑,HashSet原生支持对应O(1)复杂度的操作 public void MarkNodeDirty(Node node) { if (!dirtyNodes.Contains(node)) { dirtyNodes.Add(node); } } public void MarkNodeClean(Node node) { dirtyNodes.Remove(node); }
方案说明
- 性能符合预期:
HashSet的Contains、Add、Remove操作时间复杂度均为O(1),彻底解决原List遍历带来的性能损耗 - 无额外依赖:全程使用.NET基础类库API,不需要引入Linq,不会增加类库使用者的依赖负担
- 完全兼容原有业务逻辑:
- 不需要保证节点处理顺序,每次取任意节点更新即可
- 即使
UpdateNode()执行过程中动态新增或移除脏节点,也不会触发「枚举时集合被修改」的异常——因为每次循环只会创建一次枚举器、读取一个元素就结束枚举,下一次循环会重新读取最新的集合状态 - 循环会持续执行直到
dirtyNodes为空,和原有逻辑完全对齐
内容的提问来源于stack exchange,提问作者Clonkex
相关产品推荐
相关产品推荐

