Skip to content

Commit e9e18e7

Browse files
committed
Use ref var to avoid field descriptor copying to stack and also to avoid repeating array indexing
1 parent 1c2b89f commit e9e18e7

4 files changed

Lines changed: 35 additions & 36 deletions

File tree

Orm/Xtensive.Orm/Tuples/Packed/PackedTuple.cs

Lines changed: 16 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -46,14 +46,15 @@ public override bool Equals(Tuple other)
4646
var fieldDescriptors = PackedDescriptor.FieldDescriptors;
4747
var count = Count;
4848
for (int i = 0; i < count; i++) {
49-
var thisState = GetFieldState(ref fieldDescriptors[i]);
50-
var otherState = packedOther.GetFieldState(ref fieldDescriptors[i]);
49+
ref var descriptor = ref fieldDescriptors[i];
50+
var thisState = GetFieldState(ref descriptor);
51+
var otherState = packedOther.GetFieldState(ref descriptor);
5152
if (thisState!=otherState)
5253
return false;
5354
if (thisState!=TupleFieldState.Available)
5455
continue;
55-
var accessor = fieldDescriptors[i].Accessor;
56-
if (!accessor.ValueEquals(this, ref fieldDescriptors[i], packedOther, ref fieldDescriptors[i]))
56+
var accessor = descriptor.Accessor;
57+
if (!accessor.ValueEquals(this, ref descriptor, packedOther, ref descriptor))
5758
return false;
5859
}
5960

@@ -66,10 +67,11 @@ public override int GetHashCode()
6667
var fieldDescriptors = PackedDescriptor.FieldDescriptors;
6768
int result = 0;
6869
for (int i = 0; i < count; i++) {
69-
var accessor = fieldDescriptors[i].Accessor;
70+
ref var descriptor = ref fieldDescriptors[i];
71+
var accessor = descriptor.Accessor;
7072
var state = GetFieldState(ref fieldDescriptors[i]);
7173
var fieldHash = state==TupleFieldState.Available
72-
? accessor.GetValueHashCode(this, ref fieldDescriptors[i])
74+
? accessor.GetValueHashCode(this, ref descriptor)
7375
: 0;
7476
result = HashCodeMultiplier * result ^ fieldHash;
7577
}
@@ -83,23 +85,23 @@ public override TupleFieldState GetFieldState(int fieldIndex)
8385

8486
protected internal override void SetFieldState(int fieldIndex, TupleFieldState fieldState)
8587
{
86-
if (fieldState==TupleFieldState.Null)
87-
throw new ArgumentOutOfRangeException("fieldState");
88+
if (fieldState==TupleFieldState.Null) {
89+
throw new ArgumentOutOfRangeException(nameof(fieldState));
90+
}
8891

89-
var fieldDescriptors = PackedDescriptor.FieldDescriptors;
90-
SetFieldState(ref fieldDescriptors[fieldIndex], fieldState);
92+
SetFieldState(ref PackedDescriptor.FieldDescriptors[fieldIndex], fieldState);
9193
}
9294

9395
public override object GetValue(int fieldIndex, out TupleFieldState fieldState)
9496
{
95-
var fieldDescriptors = PackedDescriptor.FieldDescriptors;
96-
return fieldDescriptors[fieldIndex].Accessor.GetUntypedValue(this, ref fieldDescriptors[fieldIndex], out fieldState);
97+
ref var descriptor = ref PackedDescriptor.FieldDescriptors[fieldIndex];
98+
return descriptor.Accessor.GetUntypedValue(this, ref descriptor, out fieldState);
9799
}
98100

99101
public override void SetValue(int fieldIndex, object fieldValue)
100102
{
101-
var fieldDescriptors = PackedDescriptor.FieldDescriptors;
102-
fieldDescriptors[fieldIndex].Accessor.SetUntypedValue(this, ref fieldDescriptors[fieldIndex], fieldValue);
103+
ref var descriptor = ref PackedDescriptor.FieldDescriptors[fieldIndex];
104+
descriptor.Accessor.SetUntypedValue(this, ref descriptor, fieldValue);
103105
}
104106

105107
public void SetFieldState(ref PackedFieldDescriptor d, TupleFieldState fieldState)

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

Lines changed: 6 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -234,7 +234,12 @@ public static void Configure(Type[] fieldTypes, PackedFieldDescriptor[] fieldDes
234234
totalBitCount += prevCount;
235235

236236
for (var fieldIndex = 0; fieldIndex < fieldCount; fieldIndex++) {
237-
ConfigureFieldPhase2(ref fieldDescriptors[fieldIndex], ref counters);
237+
ref var descriptor = ref fieldDescriptors[fieldIndex];
238+
if (descriptor.IsObjectField) {
239+
continue;
240+
}
241+
242+
PositionUpdaterByRank[descriptor.Accessor.Rank].Invoke(ref descriptor, ref counters);
238243
}
239244

240245
valuesLength = (totalBitCount + (Val064BitCount - 1)) >> Val064Rank;
@@ -268,16 +273,6 @@ private static void ConfigureFieldPhase1(ref PackedFieldDescriptor descriptor, r
268273
descriptor.DataPosition = counters.ObjectCounter++;
269274
}
270275

271-
[MethodImpl(MethodImplOptions.AggressiveInlining)]
272-
private static void ConfigureFieldPhase2(ref PackedFieldDescriptor descriptor, ref Counters counters)
273-
{
274-
if (descriptor.IsObjectField) {
275-
return;
276-
}
277-
278-
PositionUpdaterByRank[descriptor.Accessor.Rank].Invoke(ref descriptor, ref counters);
279-
}
280-
281276
static TupleLayout()
282277
{
283278
IncrementerByRank = new CounterIncrementer[] {

Orm/Xtensive.Orm/Tuples/Tuple.cs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -112,13 +112,13 @@ public T GetValue<T>(int fieldIndex, out TupleFieldState fieldState)
112112
var isNullable = null==default(T); // Is nullable value type or class
113113

114114
if (this is PackedTuple packedTuple) {
115-
var descriptor = packedTuple.PackedDescriptor.FieldDescriptors[fieldIndex];
115+
ref var descriptor = ref packedTuple.PackedDescriptor.FieldDescriptors[fieldIndex];
116116
return descriptor.Accessor.GetValue<T>(packedTuple, ref descriptor, isNullable, out fieldState);
117117
}
118118

119119
var mappedContainer = GetMappedContainer(fieldIndex, false);
120120
if (mappedContainer.First is PackedTuple mappedTuple) {
121-
var descriptor = mappedTuple.PackedDescriptor.FieldDescriptors[mappedContainer.Second];
121+
ref var descriptor = ref mappedTuple.PackedDescriptor.FieldDescriptors[mappedContainer.Second];
122122
return descriptor.Accessor.GetValue<T>(mappedTuple, ref descriptor, isNullable, out fieldState);
123123
}
124124

@@ -187,14 +187,14 @@ public void SetValue<T>(int fieldIndex, T fieldValue)
187187
var isNullable = null==default(T); // Is nullable value type or class
188188

189189
if (this is PackedTuple packedTuple) {
190-
var descriptor = packedTuple.PackedDescriptor.FieldDescriptors[fieldIndex];
190+
ref var descriptor = ref packedTuple.PackedDescriptor.FieldDescriptors[fieldIndex];
191191
descriptor.Accessor.SetValue(packedTuple, ref descriptor, isNullable, fieldValue);
192192
return;
193193
}
194194

195195
var mappedContainer = GetMappedContainer(fieldIndex, true);
196196
if (mappedContainer.First is PackedTuple mappedTuple) {
197-
var descriptor = mappedTuple.PackedDescriptor.FieldDescriptors[mappedContainer.Second];
197+
ref var descriptor = ref mappedTuple.PackedDescriptor.FieldDescriptors[mappedContainer.Second];
198198
descriptor.Accessor.SetValue(mappedTuple, ref descriptor, isNullable, fieldValue);
199199
return;
200200
}

Orm/Xtensive.Orm/Tuples/TupleExtensions.cs

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -437,27 +437,29 @@ private static void CopyValue(Tuple source, int sourceIndex, Tuple target, int t
437437

438438
private static void CopyPackedValue(PackedTuple source, int sourceIndex, PackedTuple target, int targetIndex)
439439
{
440-
var sourceDescriptors = source.PackedDescriptor.FieldDescriptors;
441-
var targetDescriptors = target.PackedDescriptor.FieldDescriptors;
440+
ref var sourceDescriptor = ref source.PackedDescriptor.FieldDescriptors[sourceIndex];
441+
ref var targetDescriptor = ref target.PackedDescriptor.FieldDescriptors[targetIndex];
442442

443-
var fieldState = source.GetFieldState(ref sourceDescriptors[sourceIndex]);
444-
if (!fieldState.IsAvailable())
443+
var fieldState = source.GetFieldState(ref sourceDescriptor);
444+
if (!fieldState.IsAvailable()) {
445445
return;
446+
}
446447

447448
if (fieldState.IsAvailableAndNull()) {
448449
target.SetValue(targetIndex, null);
449450
return;
450451
}
451452

452-
var accessor = sourceDescriptors[sourceIndex].Accessor;
453-
if (accessor!=targetDescriptors[targetIndex].Accessor)
453+
var accessor = sourceDescriptor.Accessor;
454+
if (accessor != targetDescriptor.Accessor) {
454455
throw new InvalidOperationException(string.Format(
455456
Strings.ExInvalidCast,
456457
source.PackedDescriptor[sourceIndex],
457458
target.PackedDescriptor[targetIndex]));
459+
}
458460

459461
target.SetFieldState(targetIndex, TupleFieldState.Available);
460-
accessor.CopyValue(source, ref sourceDescriptors[sourceIndex], target, ref targetDescriptors[targetIndex]);
462+
accessor.CopyValue(source, ref sourceDescriptor, target, ref targetDescriptor);
461463
}
462464

463465
private static void PartiallyCopyTupleSlow(Tuple source, Tuple target, int sourceStartIndex, int targetStartIndex, int length)

0 commit comments

Comments
 (0)