`ReadOnlyMemory<char>`可以用作`string`的通用替代品吗?

问题描述 投票:0回答:1

以我的理解,从

ReadOnlyMemory<char>
获取
string
非常便宜,而从
string
获取
ReadOnlyMemory<char>
往往涉及分配和复制,所以不是很便宜。

幸运的是,许多过去接受

string
的 CLR 方法已经接受了接受
ReadOnlySpan<char>
的重载,这些重载可以从
ReadOnlyMemory<char>
廉价地获得,因此在许多情况下,我们可以获得
ReadOnlyMemory<char>
的性能优势,而不必替换所有我们的
string
ReadOnlyMemory<char>
。 (我们大多只需要记住在调用具有跨度接受重载的方法时将
string.Substring()
替换为
string.AsSpan().Slice()
。)

但是,在很多情况下

ReadOnlyMemory<char>
的性能优势无法实现。例如,如果我有一个带有
string
键的字典,我只能将
string
传递给它,这意味着当我想使用字符串的一部分作为键进行查找时,我别无选择,只能使用
string.Substring()
获取查找密钥,这是昂贵的。

这种情况似乎暗示,如果整个解决方案中所有

string
实例都替换为
ReadOnlyMemory<char>
,则可以实现最大性能。如果我的字典使用
ReadOnlyMemory<char>
作为键(或者聚合
readonly struct
及其哈希码的
ReadOnlyMemory<char>
,这样哈希码就不必一直重新计算),那么我将能够使用
string
ReadOnlyMemory<char>
进行高效查找。

所以,我的问题:

有没有人尝试在中等规模(不是小型)解决方案中用

string
替换所有
ReadOnlyMemory<char>

执行此类转换时可能会遇到哪些问题?

或者我错过了一些东西,实际上可以以某种方式使用子字符串(作为字典查找等的键)而无需额外的分配?

澄清:

我不是在谈论使用

ReadOnlySpan<char>
来替换
string
,因为
string
可以存在于任何地方,而
ReadOnlySpan<char>
只能存在于堆栈中,因为它是
ref struct
。另一方面,
ReadOnlyMemory<char>
是普通的
struct
,而不是
ref struct
,所以它可以生活在
string
可以生活的所有地方。

c# memory
1个回答
0
投票

虽然我以前没有做过这种替换,但是我能想到一个明显的问题。

string
是不可变的,这与只读不同。你必须知道字典默认依赖于
GetHashCode
方法。 string 的
GetHashCode
方法的实现是基于内容的,而
ReadOnlyMemory
是基于它引用的片段。

一个简单的反例:

var chars = "abc".ToCharArray();
var m = chars.AsMemory();
Console.WriteLine(m.GetHashCode());
chars[0] = 'n';
Console.WriteLine(m.GetHashCode()); // no change
© www.soinside.com 2019 - 2024. All rights reserved.