You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何高效检查C#中ReadOnlyMemory<char>是否存在于HashSet中?

高效检查ReadOnlyMemory在集合中的存在性

要在内存高效的前提下检查ReadOnlyMemory<char>是否存在于HashSet或其他集合中,核心问题是.NET默认对ReadOnlyMemory<char>的相等判断基于内存引用而非内容,所以必须通过自定义相等比较器实现内容匹配,但可以借助.NET内置扩展方法高效完成,完全避免字符串转换。

方案1:自定义IEqualityComparer<ReadOnlyMemory>

这是最直接的方案,利用MemoryExtensions提供的方法实现内容相等判断和哈希计算,无额外内存分配:

public class ReadOnlyMemoryCharEqualityComparer : IEqualityComparer<ReadOnlyMemory<char>>
{
    public bool Equals(ReadOnlyMemory<char> x, ReadOnlyMemory<char> y)
    {
        // 直接比较Span内容,无内存分配
        return x.Span.SequenceEqual(y.Span);
    }

    public int GetHashCode(ReadOnlyMemory<char> obj)
    {
        // 使用.NET内置的Span哈希算法,匹配字符串Ordinal比较逻辑
        return obj.Span.GetHashCode(StringComparison.Ordinal);
    }
}

使用方式:

// 初始化HashSet时传入自定义比较器
var memorySet = new HashSet<ReadOnlyMemory<char>>(new ReadOnlyMemoryCharEqualityComparer());

// 添加元素
memorySet.Add("example".AsMemory());

// 检查存在性
bool exists = memorySet.Contains("example".AsMemory());

方案2:使用FrozenSet提升查询性能

如果集合是只读的,推荐用System.Collections.Frozen命名空间下的FrozenSet——它会在构建时预计算哈希值,后续查询性能比普通HashSet更高,同样需要传入自定义比较器:

using System.Collections.Frozen;

// 构建只读的FrozenSet
var frozenMemorySet = new[] { "foo".AsMemory(), "bar".AsMemory() }
    .ToFrozenSet(new ReadOnlyMemoryCharEqualityComparer());

// 查询效率更优
bool exists = frozenMemorySet.Contains("foo".AsMemory());

注意事项

  • 确保ReadOnlyMemory<char>指向的内存在集合生命周期内始终有效,避免引用栈上临时内存或已释放的堆内存,否则会导致无效内存访问。
  • 若需区分大小写或特定文化的比较,可修改GetHashCode和Equals中的字符串比较规则(比如用StringComparison.OrdinalIgnoreCase)。

目前.NET原生没有无需自定义比较器的解决方案,因为ReadOnlyMemory<T>的默认相等逻辑基于内存地址而非内容。上述方案已是内存效率和性能最优的选择,完全避免了字符串转换带来的额外内存分配。

内容的提问来源于stack exchange,提问作者edwp

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.03 18:45:04