Skip to content

Commit 73ca08e

Browse files
authored
Optimization: Replace CounterIncrementer & PositionUpdater array indexing by direct reference from Accessor (#198)
* Optimization: Replace `CounterIncrementer` & `PositionUpdater` array indexing by direct reference from Accessor * Move Incrementer init into PackedFieldAccessor ctor * Remove unnecessary check * Simplify
1 parent cd9c8ff commit 73ca08e

File tree

2 files changed

+41
-55
lines changed

2 files changed

+41
-55
lines changed

Orm/Xtensive.Orm/Tuples/Packed/PackedFieldAccessor.cs

+34-1
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,11 @@
66

77
using System;
88
using System.Numerics;
9-
using System.Data.Common;
9+
using System.Runtime.CompilerServices;
1010
using Xtensive.Sql;
11+
using Counters = Xtensive.Tuples.Packed.TupleLayout.Counters;
12+
using CounterIncrementer = Xtensive.Tuples.Packed.TupleLayout.CounterIncrementer;
13+
using PositionUpdater = Xtensive.Tuples.Packed.TupleLayout.PositionUpdater;
1114

1215
namespace Xtensive.Tuples.Packed
1316
{
@@ -40,6 +43,9 @@ internal abstract class PackedFieldAccessor
4043
protected readonly long ValueBitMask;
4144
public readonly byte Index;
4245

46+
public readonly CounterIncrementer CounterIncrementer;
47+
public readonly PositionUpdater PositionUpdater;
48+
4349
public void SetValue<T>(PackedTuple tuple, PackedFieldDescriptor descriptor, bool isNullable, T value)
4450
{
4551
if ((isNullable ? NullableSetter : Setter) is SetValueDelegate<T> setter) {
@@ -82,6 +88,13 @@ public abstract bool ValueEquals(PackedTuple left, PackedFieldDescriptor leftDes
8288

8389
public abstract int GetValueHashCode(PackedTuple tuple, PackedFieldDescriptor descriptor);
8490

91+
[MethodImpl(MethodImplOptions.AggressiveInlining)]
92+
private void UpdateDescriptorPosition(ref PackedFieldDescriptor descriptor, ref int bitCounter)
93+
{
94+
descriptor.DataPosition = bitCounter;
95+
bitCounter += ValueBitCount;
96+
}
97+
8598
protected PackedFieldAccessor(int rank, byte index)
8699
{
87100
Rank = rank;
@@ -104,6 +117,26 @@ protected PackedFieldAccessor(int rank, byte index)
104117
// and then
105118
// 1000_0000 << 1 = 0000_0000
106119
ValueBitMask = (1L << (ValueBitCount - 1) << 1) - 1;
120+
121+
CounterIncrementer = Rank switch {
122+
0 => (ref Counters counters) => counters.Val001Counter++,
123+
3 => (ref Counters counters) => counters.Val008Counter++,
124+
4 => (ref Counters counters) => counters.Val016Counter++,
125+
5 => (ref Counters counters) => counters.Val032Counter++,
126+
6 => (ref Counters counters) => counters.Val064Counter++,
127+
7 => (ref Counters counters) => counters.Val128Counter++,
128+
_ => (ref Counters counters) => throw new NotSupportedException(),
129+
};
130+
131+
PositionUpdater = Rank switch {
132+
0 => (ref PackedFieldDescriptor descriptor, ref Counters counters) => UpdateDescriptorPosition(ref descriptor, ref counters.Val001Counter),
133+
3 => (ref PackedFieldDescriptor descriptor, ref Counters counters) => UpdateDescriptorPosition(ref descriptor, ref counters.Val008Counter),
134+
4 => (ref PackedFieldDescriptor descriptor, ref Counters counters) => UpdateDescriptorPosition(ref descriptor, ref counters.Val016Counter),
135+
5 => (ref PackedFieldDescriptor descriptor, ref Counters counters) => UpdateDescriptorPosition(ref descriptor, ref counters.Val032Counter),
136+
6 => (ref PackedFieldDescriptor descriptor, ref Counters counters) => UpdateDescriptorPosition(ref descriptor, ref counters.Val064Counter),
137+
7 => (ref PackedFieldDescriptor descriptor, ref Counters counters) => UpdateDescriptorPosition(ref descriptor, ref counters.Val128Counter),
138+
_ => (ref PackedFieldDescriptor descriptor, ref Counters counters) => throw new NotSupportedException()
139+
};
107140
}
108141
}
109142

Orm/Xtensive.Orm/Tuples/Packed/TupleLayout.cs

+7-54
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ internal static class TupleLayout
2020

2121
private const int Val064BitCount = 1 << Val064Rank;
2222

23-
private ref struct Counters
23+
internal ref struct Counters
2424
{
2525
public int ObjectCounter;
2626

@@ -107,13 +107,11 @@ ValueFieldAccessor ResolveByNullableType(Type type)
107107
}
108108
}
109109

110-
private delegate void CounterIncrementer(ref Counters counters);
110+
internal delegate void CounterIncrementer(ref Counters counters);
111111

112-
private delegate void PositionUpdater(ref PackedFieldDescriptor descriptor, ref Counters counters);
112+
internal delegate void PositionUpdater(ref PackedFieldDescriptor descriptor, ref Counters counters);
113113

114114
private static readonly ObjectFieldAccessor ObjectAccessor = new ObjectFieldAccessor();
115-
private static readonly CounterIncrementer[] IncrementerByRank;
116-
private static readonly PositionUpdater[] PositionUpdaterByRank;
117115

118116
[MethodImpl(MethodImplOptions.AggressiveInlining)]
119117
public static void ConfigureFieldAccessor(ref PackedFieldDescriptor descriptor, Type fieldType) =>
@@ -218,76 +216,31 @@ public static void Configure(Type[] fieldTypes, PackedFieldDescriptor[] fieldDes
218216

219217
for (var fieldIndex = 0; fieldIndex < fieldCount; fieldIndex++) {
220218
ref var descriptor = ref fieldDescriptors[fieldIndex];
221-
if (descriptor.IsObjectField()) {
222-
continue;
219+
if (!descriptor.IsObjectField()) {
220+
descriptor.GetAccessor().PositionUpdater(ref descriptor, ref counters);
223221
}
224-
225-
PositionUpdaterByRank[descriptor.GetAccessor().Rank].Invoke(ref descriptor, ref counters);
226222
}
227223

228224
valuesLength = (totalBitCount + (Val064BitCount - 1)) >> Val064Rank;
229225
objectsLength = counters.ObjectCounter;
230226
}
231227

232-
[MethodImpl(MethodImplOptions.AggressiveInlining)]
233-
private static void UpdateDescriptorPosition(ref PackedFieldDescriptor descriptor, ref int bitCounter)
234-
{
235-
descriptor.DataPosition = bitCounter;
236-
bitCounter += descriptor.GetAccessor().ValueBitCount;
237-
}
238-
239228
[MethodImpl(MethodImplOptions.AggressiveInlining)]
240229
private static void ConfigureFieldPhase1(ref PackedFieldDescriptor descriptor, ref Counters counters,
241230
Type[] fieldTypes, int fieldIndex)
242231
{
243232
descriptor.StatePosition = checked((ushort)(fieldIndex << 1));
244233

245234
ref var fieldType = ref fieldTypes[fieldIndex];
246-
var valueAccessor = ValueFieldAccessorResolver.GetValue(fieldType);
247-
if (valueAccessor != null) {
235+
if (ValueFieldAccessorResolver.GetValue(fieldType) is { } valueAccessor) {
248236
descriptor.AccessorIndex = valueAccessor.Index;
249-
250-
IncrementerByRank[valueAccessor.Rank].Invoke(ref counters);
251-
237+
valueAccessor.CounterIncrementer(ref counters);
252238
fieldType = valueAccessor.FieldType;
253239
return;
254240
}
255241

256242
descriptor.AccessorIndex = ObjectAccessor.Index;
257243
descriptor.DataPosition = counters.ObjectCounter++;
258244
}
259-
260-
static TupleLayout()
261-
{
262-
IncrementerByRank = new CounterIncrementer[] {
263-
(ref Counters counters) => counters.Val001Counter++,
264-
(ref Counters counters) => throw new NotSupportedException(),
265-
(ref Counters counters) => throw new NotSupportedException(),
266-
(ref Counters counters) => counters.Val008Counter++,
267-
(ref Counters counters) => counters.Val016Counter++,
268-
(ref Counters counters) => counters.Val032Counter++,
269-
(ref Counters counters) => counters.Val064Counter++,
270-
(ref Counters counters) => counters.Val128Counter++
271-
};
272-
273-
PositionUpdaterByRank = new PositionUpdater[] {
274-
(ref PackedFieldDescriptor descriptor, ref Counters counters)
275-
=> UpdateDescriptorPosition(ref descriptor, ref counters.Val001Counter),
276-
(ref PackedFieldDescriptor descriptor, ref Counters counters)
277-
=> throw new NotSupportedException(),
278-
(ref PackedFieldDescriptor descriptor, ref Counters counters)
279-
=> throw new NotSupportedException(),
280-
(ref PackedFieldDescriptor descriptor, ref Counters counters)
281-
=> UpdateDescriptorPosition(ref descriptor, ref counters.Val008Counter),
282-
(ref PackedFieldDescriptor descriptor, ref Counters counters)
283-
=> UpdateDescriptorPosition(ref descriptor, ref counters.Val016Counter),
284-
(ref PackedFieldDescriptor descriptor, ref Counters counters)
285-
=> UpdateDescriptorPosition(ref descriptor, ref counters.Val032Counter),
286-
(ref PackedFieldDescriptor descriptor, ref Counters counters)
287-
=> UpdateDescriptorPosition(ref descriptor, ref counters.Val064Counter),
288-
(ref PackedFieldDescriptor descriptor, ref Counters counters)
289-
=> UpdateDescriptorPosition(ref descriptor, ref counters.Val128Counter)
290-
};
291-
}
292245
}
293246
}

0 commit comments

Comments
 (0)