.net 5中基于byte*、nuint、long的指针偏移内存访问性能测试

测试环境

  • SDK:5.0.100-preview.7.20366.6
  • CPU:Intel Core i7 - 6700
  • Any CPU
  • Release

初始化测试

var sw = new Stopwatch();//计时器
var data = ((nuint)4).Allocate();//创建测试用的内存
data.Write(3, (byte)1);//为内存写入数据
data.Write(2, (byte)3);
data.Write(1, (byte)0);
data.Write(0, (byte)0);
var c = 0;//结果计数器

为避免jit的首次运行缓慢影响结果,我们使用while(true)多次测试

byte*偏移测试

//byte*偏移性能测试
c = 0;
var p = (byte*)data;
Console.WriteLine("byte*");
sw.Restart();
for (int i = 0; i < 1000000000; i++)
{
    c += p[3];
    c += p[2];
    c += p[1];
    c += p[0];
}
Console.WriteLine(sw.ElapsedMilliseconds);
Console.WriteLine(c);

nuint偏移+内联函数测试

//基于nuint偏移的内联函数性能测试
c = 0;
Console.WriteLine("M");
sw.Restart();
for (int i = 0; i < 1000000000; i++)
{
    c += data.Read<byte>(3);
    c += data.Read<byte>(2);
    c += data.Read<byte>(1);
    c += data.Read<byte>(0);
}
Console.WriteLine(sw.ElapsedMilliseconds);
Console.WriteLine(c);

其中Read实现如下:

[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static T Read<T>(this nuint ptr, nint offset) where T : unmanaged
{
    return *(T*)((nint)ptr + offset);
}

nuint偏移测试

//nuint偏移性能测试
c = 0;
Console.WriteLine("nuint");
sw.Restart();
for (int i = 0; i < 1000000000; i++)
{
    c += *(byte*)(data + 3);
    c += *(byte*)(data + 2);
    c += *(byte*)(data + 1);
    c += *(byte*)(data + 0);
}
Console.WriteLine(sw.ElapsedMilliseconds);
Console.WriteLine(c);

long偏移测试

//long偏移性能测试
c = 0;
p = (byte*)data;
Console.WriteLine("long");
sw.Restart();
for (int i = 0; i < 1000000000; i++)
{
    c += *(byte*)((long)p + 3);
    c += *(byte*)((long)p + 2);
    c += *(byte*)((long)p + 1);
    c += *(byte*)((long)p + 0);
}
Console.WriteLine(sw.ElapsedMilliseconds);
Console.WriteLine(c);

结果

所有测试用时均在1100ms左右,无明显差异

RyuJIT还是很聪明的

你可能感兴趣的:(性能测试大合集,c#,指针,.net)