优化字符串操作

Dar*_*der 5 c# string

现在是 2019 年,我们有一个使用大型机作为数据存储和交易的银行项目。

我们正在使用 DTO(Commarea,纯 c# 类),它被转换为纯字符串(这是大型机的工作方式),然后发送到大型机。

在将类转换为字符串表示时,我们使用了几种字符串操作,例如子字符串、向左填充、向右填充、修剪等。

可以想象,这会导致多次字符串分配,从而导致垃圾收集。它通常在第 0 代,但仍然如此。

特别是像Decimalwhich is a Pack typein mainframe 这样适合 8 个字节的类型会创建多个字符串。

我尝试使用ReadonlySpan<char>例如子字符串。参见示例

不过,也有类似的操作PadRightPadLeft这是不缴费的,因为它是一个只读跨度。

更新: 澄清部分转换发生如下:

val.Trim().Substring(5).PadRight(10);
Run Code Online (Sandbox Code Playgroud)

我知道这会创建 3 个字符串。我知道字符串是不可变的。我的问题是关于使用ReadonlySpanor进行上述操作Memory

我不能只将 ReadonlySpan 用于子字符串,因为一旦我调用ToString方法,我就会失去好处。

我必须ToString一路打电话到最后。

是否有另一个结构支持子字符串后面的其他操作,我实际上可以将删除数据添加到内存中?

谢谢。

小智 1

使用 ReadOnlySpan 可以帮助减少代码中的字符串分配数量,但并不能完全消除它们。这是因为 ReadOnlySpan 是字符序列的只读视图,因此您无法使用 ReadOnlySpan 修改基础数据。

为了避免不必要的字符串分配,可以使用 string.AsSpan() 方法获取字符串的 ReadOnlySpan 视图,然后使用 Span.Slice() 方法获取子字符串而不分配新字符串。例如,您可以使用以下代码来获取字符串的子字符串,而不分配新字符串:

string val = "Hello world";
ReadOnlySpan<char> span = val.AsSpan();
ReadOnlySpan<char> substring = span.Slice(5);
Run Code Online (Sandbox Code Playgroud)

但是,如前所述,您无法使用 ReadOnlySpan 来修改底层数据,因此您仍然需要为 PadRight 和 PadLeft 等操作分配新的字符串。为了避免这些分配,您可以使用 StringBuilder 逐段构建字符串,然后在完成后在 StringBuilder 上调用 ToString()。这将允许您执行字符串操作,而无需为每个操作分配新字符串。

总之,使用 ReadOnlySpan 可以帮助减少代码中的字符串分配数量,但并不能完全消除它们。为了避免为每个字符串操作分配新的字符串,您可以使用 StringBuilder 逐段构建最终的字符串。

string val = "Hello world";

StringBuilder builder = new StringBuilder(val.Length);

// Trim the string
builder.Append(val.Trim());

// Get a substring starting at the 5th character
builder.Append(val, 5, val.Length - 5);

// Pad the string with spaces to the right, to make it 10 characters long
builder.PadRight(10, ' ');

// Convert the final string to a regular string
string result = builder.ToString();
Run Code Online (Sandbox Code Playgroud)