在.Net 7中StringBuilder Insert方法优化

前言

在2月份中更新Runtime源码,发现对StingBuilder中的Insert方法进行了优化.放了一个月,看这一块代码没有继续调整.这个优化代码较少.
在.Net 7中StringBuilder的Insert方法进行优化

Insert优化主要在值类型(bool/sbyte/byte/int/long/float/double/decimal/uint/ulong),增加一个泛型方法InsertSpanFormattable.

private StringBuilder InsertSpanFormattable<T>(int index, T value) where T : ISpanFormattable
{
    Debug.Assert(typeof(T).Assembly.Equals(typeof(object).Assembly),             "Implementation trusts the results of TryFormat because T is expected to be something known");

    Span<char> buffer = stackalloc char[256];  //在栈上分配内存
    //由每个值类型的TryFormat转为字符串
    if (value.TryFormat(buffer, out int charsWritten, format: default, provider: null))
    {
        //通过接收string参数的Insert添加到内部的字符数组
        return Insert(index, buffer.Slice(0, charsWritten), 1); 
    }

    return Insert(index, value.ToString(), 1);
}

性能基准测试

[DisassemblyDiagnoser(printSource: true, maxDepth: 2)]
public class StringBuilderInsertTest
{
    public StringBuilder sb = new StringBuilder(2048);

    public StringBuilder sb1 = new StringBuilder(2048);

    [Benchmark]
    public void IntTest()
    {
        for (int times = 0; times < 5; times++)
        {
            for (int i = 0; i < 1024; i++)
            {
                sb.Insert(0, i);
            }
            sb.Clear();
        }
    }

    [Benchmark]
    public void LongTest()
    {
        for (int times = 0; times < 5; times++)
        {
            for (long i = 0; i < 1024; i++)
            {
                sb1.Insert(0, i);
            }
            sb1.Clear();
        }
    }
}

简单对Int和Long两个基础值类型进行基准测试,StringBuilder初始大小为2048.

StringBuiler中的Insert此次代码优化,性能并没有提高,只是生成的汇编代码减少五分之一

看测试结果发现int类型只是性能持平,而long类型竟然下降了一些,还好这是预览版.


秋风 2022-04-05