当前位置: 代码迷 >> 综合 >> .net 5中基于byte*、nuint、long的指针偏移内存访问性能测试
  详细解决方案

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

热度:10   发布时间:2024-02-11 15:18:09.0

测试环境

  • 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<T>实现如下:

[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还是很聪明的

  相关解决方案