在C#中将字符串复制到原始内存缓冲区的最佳方法是什么?
请注意,我已经知道如何以及何时使用String和StringBuilder,所以不建议;) - 我将需要一些文本处理&渲染代码,目前它看起来像一个内存缓冲区更容易编码和更高性能,只要我可以获取数据。 (我正在考虑B树编辑器缓冲区和内存映射文件,这些文件不能很好地映射到托管C#对象,但很容易用指针编码。)
我已经考虑过的事情:
C ++ / CLI可以做到这一点,vcclr.h中有PtrToStringChars然后可以传递给memcpy,但我通常更喜欢只有一个程序集并且从多种语言合并IL是我喜欢的避免。有什么方法可以在C#中重写该函数吗?
System.Runtime.InteropServices.Marshal具有复制字符串的功能,但仅限于新分配的缓冲区。找不到要复制到现有缓冲区的任何函数。
我可以使用String.CopyTo并使用数组而不是内存缓冲区,但是我需要将该缓冲区固定很多(或者一直保持固定),这对GC来说是不好的。 (首先使用内存缓冲区,我可以将它分配到托管堆之外,这样就不会弄乱GC。)
如果有办法固定或复制StringBuilder,那么这可能也会有效。我的文本通常来自文件或StringBuilder,所以如果我已经可以将它移动到内存缓冲区,那么它永远不需要通过String实例。 (请注意,从StringBuilder转换为String对性能无关紧要,因为如果您之后停止使用StringBuilder,则优化后不进行复制。)
我可以生成针对String或StringBuilder的IL吗?然后,不是在C#中编写复制函数,而是通过发出所需的IL来生成DynamicMethod。刚刚在编写问题时想到了这一点,所以我可能只是尝试反汇编C ++ / CLI方式并重现IL。
答案 0 :(得分:4)
启用不安全代码(项目选项中的某个位置),然后使用:
unsafe
{
fixed(char* pc = myString)
{
}
}
然后只使用低级别的内存副本。