从char[]创建不安全的字符串

本文关键字:不安全 字符串 创建 char | 更新日期: 2023-09-27 18:19:58

我正在编写一个高性能代码,其中这个构造是性能关键部分的一部分。

这就是在某些部分发生的情况:

  1. string被"扫描"并且元数据被有效地存储
  2. 基于该元数据,主串的块被分离成CCD_ 2
  3. char[][]应当被转移到string[]

现在,我知道你可以直接调用new string(char[]),但结果必须被复制。

为了避免这个额外的复制步骤发生,我想必须可以直接写入字符串的内部缓冲区。尽管这是一个不安全的操作(我知道这会带来很多影响,比如溢出、前向兼容性)。

我见过几种实现这一目标的方法,但没有一种我真正满意。

有人对如何实现这一目标有真正的建议吗?

额外信息:
实际过程并不一定包括转换为char[],它实际上是一个"多子串"操作。类似于3个索引及其附加的长度。

StringBuilder对于少量的concat有太多的开销。

编辑:
由于我所问的问题有一些模糊的方面,让我重新表述一下

这就是发生的事情:

  1. 主字符串已编入索引
  2. 主字符串的部分内容被复制到char[]
  3. 将CCD_ 9转换为CCD_

我想做的是合并步骤2和3,结果是:

  1. 主字符串已编入索引
  2. 主字符串的一部分被复制到string(GC可以通过正确使用fixed关键字在这个过程中不去管它)

需要注意的是,I不能更改string[]的输出类型,因为这是一个外部库,项目依赖于它(向后兼容性)。

从char[]创建不安全的字符串

我认为您要做的是将现有字符串"分割"为多个较小的字符串,而不为较小的字符串重新分配字符数组。这在有管理的世界里是行不通的。

原因之一是,考虑一下当垃圾收集器在压缩过程中经过并收集或移动原始字符串时会发生什么——它"内部"的所有其他字符串现在都指向某个任意的其他内存,而不是您从中提取的原始字符串。

编辑:与Ben的回答中涉及的字符戳(这很聪明,但IMHO有点可怕)相反,您可以分配一个具有预定义容量的StringBuilder,这就不需要重新分配内部数组。看见http://msdn.microsoft.com/en-us/library/h1h0a5sy.aspx.

如果这样做会发生什么:

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的速度不够快,或者这是一种假设?

只需创建自己的寻址系统,而不是试图使用不安全的代码映射到内部数据结构。

string(也可读取为char[])映射到较小字符串的数组与构建地址信息列表(每个子字符串的索引和长度)没有什么不同。因此,制作一个新的List<Tuple<int,int>>而不是string[],并使用该数据从原始的、未更改的数据结构中返回正确的字符串。这可以很容易地封装到暴露CCD_ 19的东西中。

在.NET中,无法创建与另一个字符串共享数据的String实例。关于为什么会出现这种情况的一些讨论出现在Eric Lippert的评论中。