我正在开发一个高性能代码,其中此构造是性能关键部分的一部分。
这是在某些部分中发生的事情:
string
,有效存储元数据。char[][]
。char[][]
转移到string[]
。现在,我知道您只需拨打new string(char[])
,但结果必须复制。
为了避免这个额外的复制步骤发生,我想我必须可以直接写入字符串的内部缓冲区。即使这是一个不安全的操作(我知道这会带来许多影响,如溢出,向前兼容)。
我已经看到了实现这一目标的几种方法,但没有一种我真的很满意。
有没有人对如何实现这一点有真正的建议?
额外信息:
实际过程不包括必然转换为char[]
,它实际上是一个“多子串”操作。像3个索引和它们的长度一样。
StringBuilder
对少量的会话有太多的开销。
修改
由于我所要求的一些含糊不清的方面,让我重新拟定它。
这就是:
char[]
。char[]
转换为string
。我想要做的是合并第2步和第3步,结果是:
string
(并且GC可以在此过程中通过正确使用fixed
关键字来保持其权限吗?)。请注意,我无法从string []更改输出类型,因为这是一个外部库,项目依赖于它(向后兼容性)。
答案 0 :(得分:2)
我认为你要做的就是将现有的字符串“原封”成多个较小的字符串而无需为较小的字符串重新分配字符数组。这在托管世界中无效。
出于一个原因,考虑当垃圾收集器到来并在compaction期间收集或移动原始字符串时会发生什么 - 所有其他字符串'内部'现在指向一些任意的其他内存,而不是你把它们雕刻出来的原始字符串。
编辑:与Ben的答案中涉及的字符戳(这很聪明但IMHO有点可怕)形成鲜明对比,你可以分配一个具有预定义容量的StringBuilder,这样就无需重新分配内部数组。请参阅http://msdn.microsoft.com/en-us/library/h1h0a5sy.aspx。答案 1 :(得分:2)
只需创建自己的寻址系统,而不是尝试使用不安全的代码映射到内部数据结构。
将string
(也可以作为char[]
读取)映射到较小字符串数组与构建地址信息列表(索引和每个子字符串的长度)没有区别。因此,请创建一个新的List<Tuple<int,int>>
而不是string[]
,并使用该数据从原始未更改的数据结构中返回正确的字符串。这很容易被封装到暴露string[]
的内容中。
答案 2 :(得分:2)
如果您这样做会发生什么:
string s = GetBuffer();
fixed (char* pch = s) {
pch[0] = 'R';
pch[1] = 'e';
pch[2] = 's';
pch[3] = 'u';
pch[4] = 'l';
pch[5] = 't';
}
我认为世界将会结束(或者至少是.NET管理的部分),但这与StringBuilder
非常接近。
您是否有分析器数据显示StringBuilder
对于您的目的来说不够快,或者这是一个假设?
答案 3 :(得分:0)
在.NET中,无法创建与另一个字符串共享数据的String实例。关于为什么出现的一些讨论出现在Eric Lippert的this comment中。