|
using BenchmarkDotNet.Attributes; |
|
using BenchmarkDotNet.Attributes.Columns; |
|
using BenchmarkDotNet.Attributes.Jobs; |
|
using BenchmarkDotNet.Configs; |
|
using BenchmarkDotNet.Jobs; |
|
using BenchmarkDotNet.Toolchains.CsProj; |
|
using System; |
|
|
|
namespace Bench |
|
{ |
|
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Assembly)] |
|
public class Core20JobAttribute : Attribute, IConfigSource |
|
{ |
|
public Core20JobAttribute() |
|
{ |
|
Config = ManualConfig.CreateEmpty().With(Job.Core.With(CsProjCoreToolchain.NetCoreApp20)); |
|
} |
|
|
|
public IConfig Config { get; } |
|
} |
|
|
|
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Assembly)] |
|
public class Core21JobAttribute : Attribute, IConfigSource |
|
{ |
|
public Core21JobAttribute() |
|
{ |
|
Config = ManualConfig.CreateEmpty().With(Job.Core.With(CsProjCoreToolchain.NetCoreApp21)); |
|
} |
|
|
|
public IConfig Config { get; } |
|
} |
|
|
|
[ClrJob, Core20Job, Core21Job] |
|
[MeanColumn, MinColumn, MaxColumn] |
|
[MemoryDiagnoser] |
|
public class StackallocBench |
|
{ |
|
[Benchmark] |
|
public int NormalIndexOf() |
|
{ |
|
int[] ar = new[] { 1, 4, 7, 8, 0, 1 }; |
|
for (int i = 0; i < ar.Length; i++) |
|
{ |
|
if (ar[i] == 0) |
|
{ |
|
return i; |
|
} |
|
} |
|
return -1; |
|
} |
|
|
|
[Benchmark] |
|
public int SpanIndexOf() |
|
{ |
|
Span<int> ar = stackalloc[] { 1, 4, 7, 8, 0, 1 }; |
|
for (int i = 0; i < ar.Length; i++) |
|
{ |
|
if (ar[i] == 0) |
|
{ |
|
return i; |
|
} |
|
} |
|
return -1; |
|
} |
|
|
|
public readonly struct Size8 |
|
{ |
|
public readonly int A, B; |
|
|
|
public Size8(int a, int b) |
|
{ |
|
A = a; |
|
B = b; |
|
} |
|
} |
|
|
|
public readonly struct Size16 |
|
{ |
|
public readonly int A, B, C, D; |
|
|
|
public Size16(int a, int b, int c, int d) |
|
{ |
|
A = a; |
|
B = b; |
|
C = c; |
|
D = d; |
|
} |
|
} |
|
|
|
[Benchmark] |
|
public Size8 NormalMax8() |
|
{ |
|
Span<Size8> ar = new[] { |
|
new Size8(1, 2), |
|
new Size8(2, 2), |
|
new Size8(3, 3), |
|
new Size8(1, 1) |
|
}; |
|
|
|
Size8 max = ar[0]; |
|
for (int i = 1; i < ar.Length; i++) |
|
{ |
|
Size8 x = ar[i]; |
|
if (max.A + max.B < x.A + x.B) |
|
{ |
|
max = x; |
|
} |
|
} |
|
return max; |
|
} |
|
|
|
[Benchmark] |
|
public Size8 SpanMax8() |
|
{ |
|
Span<Size8> ar = stackalloc[] { |
|
new Size8(1, 2), |
|
new Size8(2, 2), |
|
new Size8(3, 3), |
|
new Size8(1, 1) |
|
}; |
|
|
|
ref Size8 max = ref ar[0]; |
|
for (int i = 1; i < ar.Length; i++) |
|
{ |
|
ref Size8 x = ref ar[i]; |
|
if (max.A + max.B < x.A + x.B) |
|
{ |
|
max = ref x; |
|
} |
|
} |
|
return max; |
|
} |
|
|
|
[Benchmark] |
|
public Size16 NormalMax16() |
|
{ |
|
Span<Size16> ar = new[] { |
|
new Size16(1, 2, 3, 4), |
|
new Size16(2, 2, 2, 2), |
|
new Size16(3, 3, 2, 2), |
|
new Size16(1, 1, 2, 2) |
|
}; |
|
|
|
Size16 max = ar[0]; |
|
for (int i = 1; i < ar.Length; i++) |
|
{ |
|
Size16 x = ar[i]; |
|
if (max.A + max.B + max.C + max.D < x.A + x.B + x.C + x.D) |
|
{ |
|
max = x; |
|
} |
|
} |
|
return max; |
|
} |
|
|
|
[Benchmark] |
|
public Size16 SpanMax16() |
|
{ |
|
Span<Size16> ar = stackalloc[] { |
|
new Size16(1, 2, 3, 4), |
|
new Size16(2, 2, 2, 2), |
|
new Size16(3, 3, 2, 2), |
|
new Size16(1, 1, 2, 2) |
|
}; |
|
|
|
ref Size16 max = ref ar[0]; |
|
for (int i = 1; i < ar.Length; i++) |
|
{ |
|
ref Size16 x = ref ar[i]; |
|
if (max.A + max.B + max.C + max.D < x.A + x.B + x.C + x.D) |
|
{ |
|
max = ref x; |
|
} |
|
} |
|
return max; |
|
} |
|
} |
|
} |