Skip to content

Commit a7749e2

Browse files
authored
Merge pull request #14 from servicetitan/tupledescriptor-nocache
TupleDescriptor performance improvements
2 parents 4bb2ba0 + e9e18e7 commit a7749e2

43 files changed

Lines changed: 923 additions & 849 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

Extensions/Xtensive.Orm.BulkOperations/Internals/ExpressionVisitor.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -206,7 +206,7 @@ private IEnumerable<Expression> VisitExpressionList(ReadOnlyCollection<Expressio
206206
{
207207
List<Expression> list = null;
208208
for (int i = 0, n = original.Count; i < n; i++) {
209-
Expression p = Visit(original[i]);
209+
var p = Visit(original[i]);
210210
if (list!=null)
211211
list.Add(p);
212212
else if (p!=original[i]) {

Orm/Xtensive.Orm.Tests.Core/Modelling/IndexingModel/PrimaryIndexInfo.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -93,4 +93,4 @@ public PrimaryIndexInfo(TableInfo table, string name)
9393
{
9494
}
9595
}
96-
}
96+
}

Orm/Xtensive.Orm.Tests.Core/Tuples/TupleBehaviorTestBase.cs

Lines changed: 20 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,10 @@
66

77
using System;
88
using System.Collections.Generic;
9+
using System.Linq;
910
using System.Reflection;
1011
using NUnit.Framework;
11-
using Xtensive.Collections;
12-
using Xtensive.Reflection;
13-
using Xtensive.Orm.Tests;
1412
using Xtensive.Tuples;
15-
using Tuple = Xtensive.Tuples.Tuple;
1613
using MethodInfo=System.Reflection.MethodInfo;
1714

1815
namespace Xtensive.Orm.Tests.Core.Tuples
@@ -41,13 +38,10 @@ protected virtual Xtensive.Tuples.Tuple CreateTestTuple(Xtensive.Tuples.Tuple so
4138

4239
public void Test()
4340
{
44-
IList<Type> types = new List<Type>();
45-
for (int i = 0; i < 4; i++)
46-
types.Add(typeof (short));
47-
48-
TupleDescriptor descriptor = TupleDescriptor.Create(types);
49-
DummyTuple dummyTuple = new DummyTuple(descriptor);
50-
ITuple tuple = CreateTestTuple(descriptor);
41+
var types = Enumerable.Range(0, 4).Select(_ => typeof(short)).ToArray();
42+
var d = TupleDescriptor.Create(types);
43+
var dummyTuple = new DummyTuple(d);
44+
var tuple = CreateTestTuple(d);
5145
PopulateData(types, dummyTuple, tuple);
5246
AssertAreSame(dummyTuple, tuple);
5347
}
@@ -78,10 +72,8 @@ protected static void PopulateData(IList<Type> types, Xtensive.Tuples.Tuple tupl
7872

7973
public void BehaviorTest()
8074
{
81-
List<Type> fields = new List<Type>(3);
82-
fields.AddRange(new Type[] {typeof(int), typeof(bool), typeof(string)});
83-
84-
TupleDescriptor d = TupleDescriptor.Create(fields);
75+
var types = new Type[] {typeof(int), typeof(bool), typeof(string)};
76+
var d = TupleDescriptor.Create(types);
8577
TestTuple(CreateTestTuple(d));
8678
TestTuple(new DummyTuple(d));
8779
}
@@ -144,10 +136,9 @@ private static void TestTuple(Xtensive.Tuples.Tuple tuple)
144136

145137
public void EmptyFieldsTest()
146138
{
147-
List<Type> fields = new List<Type>();
148-
TupleDescriptor descriptor = TupleDescriptor.Create(fields);
149-
DummyTuple dummyTuple = new DummyTuple(descriptor);
150-
ITuple tuple = CreateTestTuple(descriptor);
139+
var d = TupleDescriptor.Create(Array.Empty<Type>());
140+
var dummyTuple = new DummyTuple(d);
141+
var tuple = CreateTestTuple(d);
151142
Assert.AreEqual(0, tuple.Count);
152143
}
153144

@@ -162,25 +153,24 @@ public void RandomTest()
162153
IList<TupleDescriptor> descriptorList = new List<TupleDescriptor>();
163154

164155
while (iteration++ < IterationCount) {
165-
int fieldCount = random.Next(0, MaxFieldCount);
166-
List<Type> fields = new List<Type>(fieldCount);
156+
var fieldCount = random.Next(0, MaxFieldCount);
157+
var types = new List<Type>(fieldCount);
167158
for (int i = 0; i < fieldCount; i++)
168-
fields.Add(fieldTypes[random.Next(0, fieldTypes.Length - 1)]);
169-
TupleDescriptor descriptor = TupleDescriptor.Create(fields);
170-
descriptorList.Add(descriptor);
159+
types.Add(fieldTypes[random.Next(0, fieldTypes.Length - 1)]);
160+
var d = TupleDescriptor.Create(types.ToArray());
161+
descriptorList.Add(d);
171162
}
172163

173164
foreach (TupleDescriptor descriptor in descriptorList) {
174-
DummyTuple dummyTuple = new DummyTuple(descriptor);
175-
ITuple tuple = CreateTestTuple(descriptor);
165+
var dummyTuple = new DummyTuple(descriptor);
166+
var tuple = CreateTestTuple(descriptor);
176167
for (int fieldIndex = 0; fieldIndex < tuple.Count / 2; fieldIndex++) {
177-
Type type = descriptor[fieldIndex];
178-
MethodInfo setValueMethod = setValueMethodGeneric.MakeGenericMethod(type);
168+
var type = descriptor[fieldIndex];
169+
var setValueMethod = setValueMethodGeneric.MakeGenericMethod(type);
179170
setValueMethod.Invoke(null, new object[] { dummyTuple, tuple, fieldIndex, random });
180171
}
181172
AssertAreSame(dummyTuple, tuple);
182173
}
183-
184174
}
185175

186176
protected void AssertAreSame(ITuple dummyTuple, ITuple tuple)
@@ -234,4 +224,4 @@ private static void InternalSetValue<T>(Xtensive.Tuples.Tuple tuple, int fieldIn
234224
tuple.SetValue(fieldIndex, instance);
235225
}
236226
}
237-
}
227+
}

Orm/Xtensive.Orm.Tests.Core/Tuples/TupleDescriptorTest.cs

Lines changed: 20 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,7 @@
77
using System;
88
using System.Collections.Generic;
99
using NUnit.Framework;
10-
using Xtensive.Collections;
11-
using Xtensive.Orm.Tests;
1210
using Xtensive.Tuples;
13-
using Tuple = Xtensive.Tuples.Tuple;
1411

1512
namespace Xtensive.Orm.Tests.Core.Tuples
1613
{
@@ -52,40 +49,38 @@ public class TupleDescriptorTest
5249
[Category("Performance")]
5350
public void PerformanceTest()
5451
{
55-
Random r = RandomManager.CreateRandom(SeedVariatorType.CallingMethod);
56-
57-
int count = 100;
58-
List<Type> types = new List<Type>();
59-
List<TupleDescriptor> descriptors = new List<TupleDescriptor>();
52+
var rnd = RandomManager.CreateRandom(SeedVariatorType.CallingMethod);
53+
var count = 100;
54+
var types = new List<Type>();
55+
var descriptors = new List<TupleDescriptor>();
6056
using (new Measurement("Creating descriptors {T1}, {T1,T2}, ...", count)) {
61-
for (int i = 0; i<count; i++) {
57+
for (var i = 0; i<count; i++) {
6258
types.Add(typeof (bool));
63-
descriptors.Add(TupleDescriptor.Create(types));
59+
descriptors.Add(TupleDescriptor.Create(types.ToArray()));
6460
}
6561
}
6662

6763
count = 1000;
68-
int maxSize = 10;
64+
var maxSize = 10;
6965
int size;
7066
using (new Measurement("Creating random descriptors", count)) {
71-
for (int i = 0; i<count; i++) {
72-
size = r.Next(maxSize);
67+
for (var i = 0; i<count; i++) {
68+
size = rnd.Next(maxSize);
7369
types = new List<Type>(size);
74-
for (int j = 0; j < size; j++)
75-
types.Add(FieldTypes[r.Next(FieldTypes.Length)]);
76-
descriptors.Add(TupleDescriptor.Create(types));
70+
for (var j = 0; j < size; j++)
71+
types.Add(FieldTypes[rnd.Next(FieldTypes.Length)]);
72+
descriptors.Add(TupleDescriptor.Create(types.ToArray()));
7773
}
7874
}
7975

8076
count = 100000;
8177
size = 10;
8278
types = new List<Type>(size);
83-
for (int j = 0; j < size; j++)
84-
types.Add(FieldTypes[r.Next(FieldTypes.Length)]);
79+
for (var j = 0; j < size; j++)
80+
types.Add(FieldTypes[rnd.Next(FieldTypes.Length)]);
8581
using (new Measurement("Creating the same descriptor", count)) {
86-
for (int i = 0; i<count; i++) {
87-
descriptors.Add(TupleDescriptor.Create(types));
88-
}
82+
for (var i = 0; i<count; i++)
83+
descriptors.Add(TupleDescriptor.Create(types.ToArray()));
8984
}
9085
}
9186

@@ -122,10 +117,10 @@ public void CombinedTest()
122117
desc = TestDescriptor(desc, new Type[] {typeof(bool?), typeof(bool), typeof(bool?)});
123118
}
124119

125-
private TupleDescriptor TestDescriptor(TupleDescriptor theSame, IList<Type> types)
120+
private TupleDescriptor TestDescriptor(TupleDescriptor theSame, Type[] types)
126121
{
127-
TupleDescriptor d1 = TupleDescriptor.Create(types);
128-
TupleDescriptor d2 = TupleDescriptor.Create(types);
122+
var d1 = TupleDescriptor.Create(types);
123+
var d2 = TupleDescriptor.Create(types);
129124
Assert.IsNotNull(d1);
130125
Assert.IsNotNull(d2);
131126
Assert.AreEqual(d1, d2);
@@ -137,4 +132,4 @@ private TupleDescriptor TestDescriptor(TupleDescriptor theSame, IList<Type> type
137132
return d1;
138133
}
139134
}
140-
}
135+
}

Orm/Xtensive.Orm.Tests.Core/Tuples/TuplePerformanceTest.cs

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
using System.Threading;
55
using NUnit.Framework;
66
using Xtensive.Comparison;
7+
using Xtensive.Core;
78
using Xtensive.Orm.Tests;
89
using Xtensive.Tuples;
910
using Tuple = Xtensive.Tuples.Tuple;
@@ -45,7 +46,10 @@ public class TuplePerformanceTest
4546
[Test]
4647
public void BasicTest()
4748
{
48-
Xtensive.Tuples.Tuple t = Xtensive.Tuples.Tuple.Create(TupleDescriptor.Create<string, int, string, TimeSpan, string, string>());
49+
var t = Tuple.Create(TupleDescriptor.Create(new [] {
50+
typeof(string), typeof(int), typeof(string),
51+
typeof(TimeSpan), typeof(string), typeof(string)
52+
}));
4953
t.SetValue(0, string.Empty);
5054
t.SetValue(2, "n\\a");
5155
t.SetValue(3, new TimeSpan());
@@ -69,11 +73,11 @@ public void GeneratorTest()
6973
Random random = RandomManager.CreateRandom(SeedVariatorType.CallingMethod);
7074
using (new Measurement("Random Tuple generation", iterationCount)) {
7175
while (iteration++ < iterationCount) {
72-
IList<Type> fieldTypesList = new List<Type>();
76+
var fieldTypes = new List<Type>();
7377
for (int i = 0; i < fieldCount; i++)
74-
fieldTypesList.Add(allFieldTypes[random.Next(allFieldTypes.Length)]);
75-
TupleDescriptor descriptor = TupleDescriptor.Create(fieldTypesList);
76-
Xtensive.Tuples.Tuple tuple = Xtensive.Tuples.Tuple.Create(descriptor);
78+
fieldTypes.Add(allFieldTypes[random.Next(allFieldTypes.Length)]);
79+
var d = TupleDescriptor.Create(fieldTypes.ToArray());
80+
var tuple = Tuple.Create(d);
7781
}
7882
}
7983
}
@@ -414,7 +418,8 @@ public void GeneratorAdvancedTest()
414418
for (int i = 0; i < runCount; i++) {
415419
var count = sizeRandomizer.Next(maxSize + 1);
416420
var tupleTypes = Enumerable.Repeat(0, count)
417-
.Select(_ => types[typeRandomizer.Next(types.Length)]);
421+
.Select(_ => types[typeRandomizer.Next(types.Length)])
422+
.ToArray(count);
418423
var descriptor = TupleDescriptor.Create(tupleTypes);
419424
var tuple = Tuple.Create(descriptor);
420425
}

Orm/Xtensive.Orm/Collections/ArrayUtils.cs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
// Created: 2007.07.04
77

88
using System;
9+
using System.Runtime.CompilerServices;
910

1011
namespace Xtensive.Collections
1112
{
@@ -15,13 +16,12 @@ namespace Xtensive.Collections
1516
/// <typeparam name="TItem">Type of array item.</typeparam>
1617
public static class ArrayUtils<TItem>
1718
{
18-
private static readonly TItem[] emptyArray = new TItem[] {};
19-
2019
/// <summary>
2120
/// Gets empty array of items of <typeparamref name="TItem"/> type.
2221
/// </summary>
2322
public static TItem[] EmptyArray {
24-
get { return emptyArray; }
23+
[MethodImpl(MethodImplOptions.AggressiveInlining)]
24+
get => Array.Empty<TItem>();
2525
}
2626
}
27-
}
27+
}

Orm/Xtensive.Orm/Collections/DirectionCollection.cs

Lines changed: 11 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,13 @@ namespace Xtensive.Collections
2222
[DebuggerDisplay("Count = {Count}")]
2323
public sealed class DirectionCollection<T>: FlagCollection<T, Direction>
2424
{
25+
private static readonly Biconverter<Direction, bool> DirectionToBoolBiconverter =
26+
new Biconverter<Direction, bool>(
27+
value => value == Direction.None
28+
? throw Exceptions.InvalidArgument(value, nameof(value))
29+
: value == Direction.Positive,
30+
value => value ? Direction.Positive : Direction.Negative);
31+
2532
/// <inheritdoc/>
2633
public override void Add(T key)
2734
{
@@ -33,13 +40,7 @@ public override void Add(T key)
3340
/// </summary>
3441
/// <param name="enumerable">Initial content of collection.</param>
3542
public DirectionCollection(IEnumerable<KeyValuePair<T, Direction>> enumerable)
36-
: base(new Biconverter<Direction, bool>(
37-
delegate (Direction value) {
38-
if (value==Direction.None)
39-
throw Exceptions.InvalidArgument(value, "value");
40-
return value == Direction.Positive;
41-
},
42-
delegate(bool value) { return value ? Direction.Positive : Direction.Negative; }),
43+
: base(DirectionToBoolBiconverter,
4344
enumerable)
4445
{
4546
}
@@ -49,13 +50,7 @@ public DirectionCollection(IEnumerable<KeyValuePair<T, Direction>> enumerable)
4950
/// </summary>
5051
/// <param name="items">Initial content of collection.</param>
5152
public DirectionCollection(params T[] items)
52-
: base(new Biconverter<Direction, bool>(
53-
value => {
54-
if (value==Direction.None)
55-
throw Exceptions.InvalidArgument(value, "value");
56-
return value==Direction.Positive;
57-
},
58-
value => value ? Direction.Positive : Direction.Negative))
53+
: base(DirectionToBoolBiconverter)
5954
{
6055
foreach (T item in items)
6156
Add(item, Direction.Positive);
@@ -65,14 +60,8 @@ public DirectionCollection(params T[] items)
6560
/// Initializes a new instance of this type.
6661
/// </summary>
6762
public DirectionCollection()
68-
: base(new Biconverter<Direction, bool>(
69-
value => {
70-
if (value==Direction.None)
71-
throw Exceptions.InvalidArgument(value, "value");
72-
return value==Direction.Positive;
73-
},
74-
value => value ? Direction.Positive : Direction.Negative))
63+
: base(DirectionToBoolBiconverter)
7564
{
7665
}
7766
}
78-
}
67+
}

0 commit comments

Comments
 (0)