为什么在下面的代码上运行基准测试,显示方法
BuildString
没有内存分配?我不明白,因为据我所知,字符串应该分配在堆上。
[MemoryDiagnoser]
public class StringBenchmark
{
[Benchmark]
public string BuildString()
{
return "Test";
}
[Benchmark]
public string BuildStringUsingStringConcatenationMethod()
{
return string.Concat("Hello", 2022, "/", 5);
}
}
基准测试结果:
方法 | 意思是 | 错误 | 标准偏差 | 0代 | 已分配 |
---|---|---|---|---|---|
构建字符串 | 0.0000 纳秒 | 0.0000 纳秒 | 0.0000 纳秒 | - | - |
使用字符串连接方法构建字符串 | 60.0764 纳秒 | 0.4336 纳秒 | 0.3385 纳秒 | 0.0286 | 240B |
编译器可以自由地使用“interned”字符串作为文字,即每次在代码中使用
"abc"
时,它都可以使用 "abc"
的 same实例。这包括编译器在构建期间可以计算为常量的表达式,例如other常量表达式的串联。
您可以检查一下:
using System;
string a = Strings.Fixed(), b = Strings.Fixed(),
c = Strings.New(), d = Strings.New();
// writes "abc; equal? True; same? True"
Console.WriteLine($"{a}; equal? {string.Equals(a,b)}; same? {ReferenceEquals(a,b)}");
// writes "def; equal? True; same? False"
Console.WriteLine($"{c}; equal? {string.Equals(c,d)}; same? {ReferenceEquals(c,d)}");
static class Strings
{
// returns interned instance
public static string Fixed() => "abc";
// creates a new instance each time
public static string New() => new string("def".AsSpan());
}