【发布时间】:2019-04-14 16:48:47
【问题描述】:
我们如何使用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 需要指向堆中的某个位置。 我的问题是,我们如何才能指向字符串的一个子集而不将该部分复制到堆内存的新位置?
我知道一个新的构造函数已添加到接受ReadOnlySpan<T> 的 String 类中,例如:
var firstName = new string(span);
但是无论是否通过在堆上分配来完成,我都找不到任何地方。
【问题讨论】:
-
使用
new string(…),您将获得全新的string对象,该对象必须分配到某个地方。并且由于它可以比当前方法寿命更长,因此不能在堆栈上分配。 -
@PetSerAl
Span<T>位于堆栈上,但其内容可能位于堆上。因此,通过使用new string(span),我们正在创建一个可以指向堆中某处的指针。 -
您的问题是——分配给
firstName的new string是在堆上分配的吗?如果是这样,答案是肯定的——字符串总是在堆上分配的。我的后续问题是 - 你为什么在乎?你的根本问题是什么?这感觉像是一个 XY 问题 - meta.stackexchange.com/questions/66377/what-is-the-xy-problem。 或者您是在问span(这完全是一个不同的问题)? -
简单测试,
var firstName = new string(span)修改span后告诉我们你创建的字符串发生了什么,你会回答你的问题 -
不,你不能那样做。
标签: c# string performance memory substring