优化Benchmark测试初始参数
起因
在 <<在.Net 7中String的Equals和StartWith性能优化>> 一文中,今天在看初始化性能基准测试参数代码时,感觉这一块还是可以调整一下的.本文比较水,优化代码的方式可以以前写的文章: 编码中代码优化 ,使用硬件指令优化,是这几年.Net社区一直在做的事情,从.Net Core 3.1开始,到.Net 7(从X86到ARM,使用更多的硬件指令优化).
看最近在ARM架构优化:

调整后代码
namespace net6perf.StringFunction
{
[DisassemblyDiagnoser(printSource: true, maxDepth: 3)]
[MemoryDiagnoser]
public class CharTest
{
[Params(1024, 2048, 4096)]
public int Count;
/// <summary>
/// 第一版
/// </summary>
[Benchmark]
public void Test1()
{
char[] chars = new char[52];
for (int i = 0; i < Count; i++)
{
int index = 0;
for (int j = 65; j < 123; j++)
{
if (j > 90 && j < 97)
{
continue;
}
chars[index] = (char)j;
index++;
}
}
}
/// <summary>
/// 第二版 减少循环中判断,提高CPU分支预测的命中率
/// 将循环拆分为2个循环
/// </summary>
[Benchmark]
public void Test2()
{
char[] chars = new char[52];
for (int i = 0; i < Count; i++)
{
for (int j = 0; j < 26; j++)
{
chars[j] = (char)(j + 65);
}
for (int j = 0; j < 26; j++)
{
chars[j + 26] = (char)(j + 97);
}
}
}
/// <summary>
/// 第三版 循环展开,减少循环的次数
/// 1. 一次处理 chars[0] ='A'; chars[26] = 'a';
/// 2. 减少计算次数 (char)j+65
/// 3. 减少加法运算,使用位或运算
/// </summary>
[Benchmark]
public void Test3()
{
char[] chars = new char[52];
for (int i = 0; i < Count; i++)
{
for (int j = 0; j < 26; j++)
{
char c = (char)(j + 65);
chars[j] = c;
chars[j + 26] = (char)(c | 32);
}
}
}
}
}
BenchmarkDotNet性能基准测试结果.

Test2将循环拆分为2个,不在进行条件判断,在性能上比Test1提高3倍多,Test3比Test2提升不明显,提高了3微妙.
秋风
2022-02-20