繁体   English   中英

在 C# 个字符串对象之间共享字符缓冲区

[英]Sharing character buffer between C# strings objects

这可能吗? 鉴于 C# 使用不可变字符串,可以预期会有一种方法如下:

var expensive = ReadHugeStringFromAFile();
var cheap = expensive.SharedSubstring(1);

如果没有这样的 function,为什么还要费心让字符串不可变呢? 或者,如果字符串由于其他原因已经不可变,为什么不提供此方法?

我正在研究这个的具体原因是进行一些文件解析。 简单的递归下降解析器(例如由 TinyPG 生成的解析器,或易于手工编写的解析器)到处都使用 Substring。 这意味着如果你给他们一个大文件来解析,memory 的流失是难以置信的。 当然有解决方法 - 基本上推出你自己的 SubString class,然后当然忘记能够使用字符串方法,如 StartsWith 或字符串库,如 Regex,所以你也需要推出你自己的版本。 我假设像 ANTLR 这样的解析器生成器基本上可以做到这一点,但我的格式很简单,不能证明使用这样一个怪物工具是合理的。 即使是 TinyPG 也可能有点矫枉过正。

有人请告诉我我在某处遗漏了一些明显或不那么明显的标准 C# 方法调用......

不,没有那样的事。

.NET 字符串直接包含它们的文本数据,这与 Java 字符串不同,后者具有对 char 数组、偏移量和长度的引用。

这两种解决方案在某些情况下都有“胜利”,而在其他情况下则有损失。

如果您绝对确定这对您来说是致命的,您可以实现一个 Java 样式的字符串以在您自己的内部 API 中使用。

据我所知,所有较大的解析器都使用流来解析。 这不适合你的情况吗?

.NET 框架支持字符串实习 这是一个部分解决方案,但不提供重用部分字符串的可能性。 我认为重用 substring 会导致一些乍一看并不明显的问题。 如果您必须使用StringBuilder进行大量字符串操作,则可以使用 go。

C# 中没有任何内容可以为您提供您正在寻找的开箱即用功能。

需要的是一个Rope 数据结构,一个支持 O(1) concats 和 O(log n) 子串的不可变数据结构。 我找不到绳子的任何 C# 实现,但这里是 Java 一个

除此之外,如果这是完成任务的最简单方法,那么使用 TinyPG 或 ANTLR 并没有错。

那么你可以使用“不安全”来自己做 memory 管理,这可能会让你做你正在寻找的事情。 此外,StringBuilder class 非常适合需要多次操作字符串的情况,因为它不会在每次操作时生成新字符串。

您可以轻松编写一个普通的 class 来表示“便宜”。 它只会保存 substring 的开头索引和 substring 的长度。有几种方法可以让您在需要时读取 substring - 字符串转换运算符将是您可以使用的理想选择

string text = myCheapObject;

并且它会像实际的字符串一样无缝地工作。 添加对一些方便方法(如 StartsWith)的支持将既快速又容易(它们都是一个衬里)。

另一种选择是编写常规解析器并将您的标记存储在字典中,您可以从中共享对标记的引用,而不是保留多个副本。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM