-
Notifications
You must be signed in to change notification settings - Fork 11
/
ArrayOfBigStructSum.cs
132 lines (114 loc) · 3.54 KB
/
ArrayOfBigStructSum.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
using System;
using System.Linq;
using System.Runtime.CompilerServices;
using BenchmarkDotNet.Attributes;
namespace StructLinq.Benchmark
{
[MemoryDiagnoser]
public class ArrayOfBigStructSum
{
private const int Count = 1000;
private readonly StructContainer[] array;
public ArrayOfBigStructSum()
{
array = Enumerable.Range(0, Count).Select(StructContainer.Create).ToArray();
}
[Benchmark]
public int Handmaded()
{
int sum = 0;
for (int i = 0; i < Count; i++)
{
sum += array[i].Element;
}
return sum;
}
[Benchmark(Baseline = true)]
public int SysEnumerableSum()
{
return array.Sum(x => x.Element);
}
[Benchmark]
public int StructSum()
{
return array.ToStructEnumerable()
.Sum(x=> x.Element);
}
[Benchmark]
public int RefStructSum()
{
return array.ToRefStructEnumerable()
.Sum((in StructContainer element) => element.Element);
}
[Benchmark]
public int ZeroAllocStructSum()
{
var @select = new StructContainerSelect();
return array.ToStructEnumerable()
.Sum(ref @select, x => x, x => x);
}
[Benchmark]
public int ZeroAllocRefStructSum()
{
var @select = new InStructContainerSelect();
return array.ToRefStructEnumerable()
.Sum(ref @select, x => x, x => x);
}
}
internal struct StructContainerSelect : IFunction<StructContainer, int>
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public readonly int Eval(StructContainer element)
{
return element.Element;
}
}
internal struct InStructContainerSelect : IInFunction<StructContainer, int>
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public readonly int Eval(in StructContainer element)
{
return element.Element;
}
}
internal struct StructContainer : IEquatable<StructContainer>
{
public readonly int Element;
public bool Equals(StructContainer other)
{
return Element == other.Element;
}
public override bool Equals(object obj)
{
return obj is StructContainer other && Equals(other);
}
public override int GetHashCode()
{
return Element;
}
public readonly int Element1;
public readonly int Element2;
public readonly int Element3;
public readonly int Element4;
public readonly int Element5;
public readonly int Element6;
public readonly int Element7;
public readonly int Element8;
public StructContainer(int element, int element1, int element2, int element3, int element4, int element5, int element6, int element7, int element8)
{
Element = element;
Element1 = element1;
Element2 = element2;
Element3 = element3;
Element4 = element4;
Element5 = element5;
Element6 = element6;
Element7 = element7;
Element8 = element8;
}
public static StructContainer Create(int element)
{
return new StructContainer(element, element, element, element, element, element, element, element, element);
}
}
}