没有使用Span <t>进行任何分配的子字符串

时间:2018-11-11 23:06:37

标签: c# string performance memory substring

为了消除堆分配的必要性,我们如何使用Span<T>而不是string.Substring?假设我们有以下代码:

var firstNameAndFamilyName="myname,myfamily";
var span = firstNameAndFamilyName.AsSpan().Slice(0,6);
var firstName = .... //  How can I get 'myname' without allocating any new memory on the heap?

请注意,我知道字符串"myname,myfamily"位于堆上,firstName需要指向堆中的某个位置。 我的问题是,我们如何指向一个字符串子集,而又不将该部分对应到堆内存的新位置?

我知道已经向String类添加了一个新的构造函数,该构造函数接受ReadOnlySpan<T>如下:

var firstName = new string(span);

但是我找不到任何地方是否通过在堆上分配来完成。

1 个答案:

答案 0 :(得分:4)

众所周知,System.String is immutable。不,但是,如果。如果您有Span<char>,并且想将它们视为string,则会分配新的内存。

好消息是,随着Span<>的引入,除接受字符串和数组之外,该框架中的许多内置方法也进行了更新以接受。引用this MSDN article(我已经添加了一些示例的链接):

  

..已在整个框架中添加了许多此类方法。从System.RandomSystem.Text.StringBuilderSystem.Net.Sockets,已经添加了重载功能,从而使{ReadOnly}Span<T>{ReadOnly}Memory<T>的使用变得简单而高效。

这还包括所有数字{Try}Parse(string)方法,现在将具有相应的(ReadOnlySpan<char>) overloads

var str = "123,456";
var span = str.AsSpan(0,3);
var i = int.Parse(span);

因此,不要让string超出范围,而是看看您要实现的目标是否可以直接利用Span<>