Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
21bc371
TupleDescriptor-related performance improvements.
alexyakunin Feb 4, 2020
b6430ae
More performance related fixes based on profiling.
alexyakunin Feb 4, 2020
b0de0f7
Convert PackedFieldDescriptor to struct and pass it by reference ever…
AlexUstinov Mar 14, 2020
ac415e5
Use lightweight data type while sorting FieldDescriptors. Get rid of …
AlexUstinov Mar 16, 2020
66824b7
No Array.Sort() method call in TupleDescriptor's constructor
AlexUstinov Mar 18, 2020
d06056d
Precise calculation of ValuesLength property
AlexUstinov Mar 18, 2020
af7eb92
Move all packed field layout configuration code to TupleLayout class
AlexUstinov Mar 18, 2020
1e8113f
Organize code in TupleLayout class
AlexUstinov Mar 18, 2020
eef85ec
Make code resistant to sign bit propagation by right shift operator
AlexUstinov Mar 18, 2020
03234ac
Explanation of ValueBitMask calculation
AlexUstinov Mar 18, 2020
1ca12b7
TypeInfo.BuildVersionExtractor method improvements
AlexUstinov Mar 25, 2020
c1db7b2
ItemToTupleConverter improvements
AlexUstinov Mar 25, 2020
44197e1
Tail and Head methods improvements
AlexUstinov Mar 30, 2020
c403616
Cache BoolType and BoolTypeDescriptor
AlexUstinov Mar 30, 2020
2ecce7b
Do not create new empty array on field initialization
AlexUstinov Mar 30, 2020
1ff4573
Small KeyFactory improvement
AlexUstinov Apr 1, 2020
2cf5c03
Bump version to 6.0.2 'tupledescriptor'
AlexUstinov Mar 26, 2020
1ee5741
Get rid of TupleDescriptor caches
AlexUstinov Apr 2, 2020
28c23c7
Introduce ValueFieldAccessorResolver
AlexUstinov Apr 1, 2020
337191f
Make TupleDescriptor IReadonlyList<T> instead of IList<T>
AlexUstinov Apr 2, 2020
ec1fe11
Make separate configuration methods for descriptors of length 1 and 2
AlexUstinov Apr 2, 2020
a865d16
TupleDescriptor code cleanup
AlexUstinov Apr 2, 2020
38f1efc
Use MetadataToken to detect if type is nullable (this is a little bit…
AlexUstinov Mar 30, 2020
8bf9e1f
Move Rank, ValueBitCount and ValueBitMask properties to Accessor to s…
AlexUstinov Apr 2, 2020
4bb6b2b
Get rid of ValuePointer structure to improve performance
AlexUstinov Apr 2, 2020
bb7a67c
Get rid of ValuePointerS structure to decrease stack allocation size …
AlexUstinov Apr 1, 2020
8cfbc20
Directly write to PackedFieldDescriptor fields to save on setter calls
AlexUstinov Apr 1, 2020
5156284
Bump version to 6.0.3 'tupledescriptor-nocache'
AlexUstinov Apr 2, 2020
404a5f3
Remove version suffix
AlexUstinov Apr 2, 2020
1c2b89f
Use Array.Empty to get empty array instance
AlexUstinov Apr 2, 2020
e9e18e7
Use ref var to avoid field descriptor copying to stack and also to av…
AlexUstinov Apr 3, 2020
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -206,7 +206,7 @@ private IEnumerable<Expression> VisitExpressionList(ReadOnlyCollection<Expressio
{
List<Expression> list = null;
for (int i = 0, n = original.Count; i < n; i++) {
Expression p = Visit(original[i]);
var p = Visit(original[i]);
if (list!=null)
list.Add(p);
else if (p!=original[i]) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -93,4 +93,4 @@ public PrimaryIndexInfo(TableInfo table, string name)
{
}
}
}
}
50 changes: 20 additions & 30 deletions Orm/Xtensive.Orm.Tests.Core/Tuples/TupleBehaviorTestBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,10 @@

using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using NUnit.Framework;
using Xtensive.Collections;
using Xtensive.Reflection;
using Xtensive.Orm.Tests;
using Xtensive.Tuples;
using Tuple = Xtensive.Tuples.Tuple;
using MethodInfo=System.Reflection.MethodInfo;

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

public void Test()
{
IList<Type> types = new List<Type>();
for (int i = 0; i < 4; i++)
types.Add(typeof (short));

TupleDescriptor descriptor = TupleDescriptor.Create(types);
DummyTuple dummyTuple = new DummyTuple(descriptor);
ITuple tuple = CreateTestTuple(descriptor);
var types = Enumerable.Range(0, 4).Select(_ => typeof(short)).ToArray();
var d = TupleDescriptor.Create(types);
var dummyTuple = new DummyTuple(d);
var tuple = CreateTestTuple(d);
PopulateData(types, dummyTuple, tuple);
AssertAreSame(dummyTuple, tuple);
}
Expand Down Expand Up @@ -78,10 +72,8 @@ protected static void PopulateData(IList<Type> types, Xtensive.Tuples.Tuple tupl

public void BehaviorTest()
{
List<Type> fields = new List<Type>(3);
fields.AddRange(new Type[] {typeof(int), typeof(bool), typeof(string)});

TupleDescriptor d = TupleDescriptor.Create(fields);
var types = new Type[] {typeof(int), typeof(bool), typeof(string)};
var d = TupleDescriptor.Create(types);
TestTuple(CreateTestTuple(d));
TestTuple(new DummyTuple(d));
}
Expand Down Expand Up @@ -144,10 +136,9 @@ private static void TestTuple(Xtensive.Tuples.Tuple tuple)

public void EmptyFieldsTest()
{
List<Type> fields = new List<Type>();
TupleDescriptor descriptor = TupleDescriptor.Create(fields);
DummyTuple dummyTuple = new DummyTuple(descriptor);
ITuple tuple = CreateTestTuple(descriptor);
var d = TupleDescriptor.Create(Array.Empty<Type>());
var dummyTuple = new DummyTuple(d);
var tuple = CreateTestTuple(d);
Assert.AreEqual(0, tuple.Count);
}

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

while (iteration++ < IterationCount) {
int fieldCount = random.Next(0, MaxFieldCount);
List<Type> fields = new List<Type>(fieldCount);
var fieldCount = random.Next(0, MaxFieldCount);
var types = new List<Type>(fieldCount);
for (int i = 0; i < fieldCount; i++)
fields.Add(fieldTypes[random.Next(0, fieldTypes.Length - 1)]);
TupleDescriptor descriptor = TupleDescriptor.Create(fields);
descriptorList.Add(descriptor);
types.Add(fieldTypes[random.Next(0, fieldTypes.Length - 1)]);
var d = TupleDescriptor.Create(types.ToArray());
descriptorList.Add(d);
}

foreach (TupleDescriptor descriptor in descriptorList) {
DummyTuple dummyTuple = new DummyTuple(descriptor);
ITuple tuple = CreateTestTuple(descriptor);
var dummyTuple = new DummyTuple(descriptor);
var tuple = CreateTestTuple(descriptor);
for (int fieldIndex = 0; fieldIndex < tuple.Count / 2; fieldIndex++) {
Type type = descriptor[fieldIndex];
MethodInfo setValueMethod = setValueMethodGeneric.MakeGenericMethod(type);
var type = descriptor[fieldIndex];
var setValueMethod = setValueMethodGeneric.MakeGenericMethod(type);
setValueMethod.Invoke(null, new object[] { dummyTuple, tuple, fieldIndex, random });
}
AssertAreSame(dummyTuple, tuple);
}

}

protected void AssertAreSame(ITuple dummyTuple, ITuple tuple)
Expand Down Expand Up @@ -234,4 +224,4 @@ private static void InternalSetValue<T>(Xtensive.Tuples.Tuple tuple, int fieldIn
tuple.SetValue(fieldIndex, instance);
}
}
}
}
45 changes: 20 additions & 25 deletions Orm/Xtensive.Orm.Tests.Core/Tuples/TupleDescriptorTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,7 @@
using System;
using System.Collections.Generic;
using NUnit.Framework;
using Xtensive.Collections;
using Xtensive.Orm.Tests;
using Xtensive.Tuples;
using Tuple = Xtensive.Tuples.Tuple;

namespace Xtensive.Orm.Tests.Core.Tuples
{
Expand Down Expand Up @@ -52,40 +49,38 @@ public class TupleDescriptorTest
[Category("Performance")]
public void PerformanceTest()
{
Random r = RandomManager.CreateRandom(SeedVariatorType.CallingMethod);

int count = 100;
List<Type> types = new List<Type>();
List<TupleDescriptor> descriptors = new List<TupleDescriptor>();
var rnd = RandomManager.CreateRandom(SeedVariatorType.CallingMethod);
var count = 100;
var types = new List<Type>();
var descriptors = new List<TupleDescriptor>();
using (new Measurement("Creating descriptors {T1}, {T1,T2}, ...", count)) {
for (int i = 0; i<count; i++) {
for (var i = 0; i<count; i++) {
types.Add(typeof (bool));
descriptors.Add(TupleDescriptor.Create(types));
descriptors.Add(TupleDescriptor.Create(types.ToArray()));
}
}

count = 1000;
int maxSize = 10;
var maxSize = 10;
int size;
using (new Measurement("Creating random descriptors", count)) {
for (int i = 0; i<count; i++) {
size = r.Next(maxSize);
for (var i = 0; i<count; i++) {
size = rnd.Next(maxSize);
types = new List<Type>(size);
for (int j = 0; j < size; j++)
types.Add(FieldTypes[r.Next(FieldTypes.Length)]);
descriptors.Add(TupleDescriptor.Create(types));
for (var j = 0; j < size; j++)
types.Add(FieldTypes[rnd.Next(FieldTypes.Length)]);
descriptors.Add(TupleDescriptor.Create(types.ToArray()));
}
}

count = 100000;
size = 10;
types = new List<Type>(size);
for (int j = 0; j < size; j++)
types.Add(FieldTypes[r.Next(FieldTypes.Length)]);
for (var j = 0; j < size; j++)
types.Add(FieldTypes[rnd.Next(FieldTypes.Length)]);
using (new Measurement("Creating the same descriptor", count)) {
for (int i = 0; i<count; i++) {
descriptors.Add(TupleDescriptor.Create(types));
}
for (var i = 0; i<count; i++)
descriptors.Add(TupleDescriptor.Create(types.ToArray()));
}
}

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

private TupleDescriptor TestDescriptor(TupleDescriptor theSame, IList<Type> types)
private TupleDescriptor TestDescriptor(TupleDescriptor theSame, Type[] types)
{
TupleDescriptor d1 = TupleDescriptor.Create(types);
TupleDescriptor d2 = TupleDescriptor.Create(types);
var d1 = TupleDescriptor.Create(types);
var d2 = TupleDescriptor.Create(types);
Assert.IsNotNull(d1);
Assert.IsNotNull(d2);
Assert.AreEqual(d1, d2);
Expand All @@ -137,4 +132,4 @@ private TupleDescriptor TestDescriptor(TupleDescriptor theSame, IList<Type> type
return d1;
}
}
}
}
17 changes: 11 additions & 6 deletions Orm/Xtensive.Orm.Tests.Core/Tuples/TuplePerformanceTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
using System.Threading;
using NUnit.Framework;
using Xtensive.Comparison;
using Xtensive.Core;
using Xtensive.Orm.Tests;
using Xtensive.Tuples;
using Tuple = Xtensive.Tuples.Tuple;
Expand Down Expand Up @@ -45,7 +46,10 @@ public class TuplePerformanceTest
[Test]
public void BasicTest()
{
Xtensive.Tuples.Tuple t = Xtensive.Tuples.Tuple.Create(TupleDescriptor.Create<string, int, string, TimeSpan, string, string>());
var t = Tuple.Create(TupleDescriptor.Create(new [] {
typeof(string), typeof(int), typeof(string),
typeof(TimeSpan), typeof(string), typeof(string)
}));
t.SetValue(0, string.Empty);
t.SetValue(2, "n\\a");
t.SetValue(3, new TimeSpan());
Expand All @@ -69,11 +73,11 @@ public void GeneratorTest()
Random random = RandomManager.CreateRandom(SeedVariatorType.CallingMethod);
using (new Measurement("Random Tuple generation", iterationCount)) {
while (iteration++ < iterationCount) {
IList<Type> fieldTypesList = new List<Type>();
var fieldTypes = new List<Type>();
for (int i = 0; i < fieldCount; i++)
fieldTypesList.Add(allFieldTypes[random.Next(allFieldTypes.Length)]);
TupleDescriptor descriptor = TupleDescriptor.Create(fieldTypesList);
Xtensive.Tuples.Tuple tuple = Xtensive.Tuples.Tuple.Create(descriptor);
fieldTypes.Add(allFieldTypes[random.Next(allFieldTypes.Length)]);
var d = TupleDescriptor.Create(fieldTypes.ToArray());
var tuple = Tuple.Create(d);
}
}
}
Expand Down Expand Up @@ -414,7 +418,8 @@ public void GeneratorAdvancedTest()
for (int i = 0; i < runCount; i++) {
var count = sizeRandomizer.Next(maxSize + 1);
var tupleTypes = Enumerable.Repeat(0, count)
.Select(_ => types[typeRandomizer.Next(types.Length)]);
.Select(_ => types[typeRandomizer.Next(types.Length)])
.ToArray(count);
var descriptor = TupleDescriptor.Create(tupleTypes);
var tuple = Tuple.Create(descriptor);
}
Expand Down
8 changes: 4 additions & 4 deletions Orm/Xtensive.Orm/Collections/ArrayUtils.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
// Created: 2007.07.04

using System;
using System.Runtime.CompilerServices;

namespace Xtensive.Collections
{
Expand All @@ -15,13 +16,12 @@ namespace Xtensive.Collections
/// <typeparam name="TItem">Type of array item.</typeparam>
public static class ArrayUtils<TItem>
{
private static readonly TItem[] emptyArray = new TItem[] {};

/// <summary>
/// Gets empty array of items of <typeparamref name="TItem"/> type.
/// </summary>
public static TItem[] EmptyArray {
get { return emptyArray; }
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get => Array.Empty<TItem>();
}
}
}
}
33 changes: 11 additions & 22 deletions Orm/Xtensive.Orm/Collections/DirectionCollection.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,13 @@ namespace Xtensive.Collections
[DebuggerDisplay("Count = {Count}")]
public sealed class DirectionCollection<T>: FlagCollection<T, Direction>
{
private static readonly Biconverter<Direction, bool> DirectionToBoolBiconverter =
new Biconverter<Direction, bool>(
value => value == Direction.None
? throw Exceptions.InvalidArgument(value, nameof(value))
: value == Direction.Positive,
value => value ? Direction.Positive : Direction.Negative);

/// <inheritdoc/>
public override void Add(T key)
{
Expand All @@ -33,13 +40,7 @@ public override void Add(T key)
/// </summary>
/// <param name="enumerable">Initial content of collection.</param>
public DirectionCollection(IEnumerable<KeyValuePair<T, Direction>> enumerable)
: base(new Biconverter<Direction, bool>(
delegate (Direction value) {
if (value==Direction.None)
throw Exceptions.InvalidArgument(value, "value");
return value == Direction.Positive;
},
delegate(bool value) { return value ? Direction.Positive : Direction.Negative; }),
: base(DirectionToBoolBiconverter,
enumerable)
{
}
Expand All @@ -49,13 +50,7 @@ public DirectionCollection(IEnumerable<KeyValuePair<T, Direction>> enumerable)
/// </summary>
/// <param name="items">Initial content of collection.</param>
public DirectionCollection(params T[] items)
: base(new Biconverter<Direction, bool>(
value => {
if (value==Direction.None)
throw Exceptions.InvalidArgument(value, "value");
return value==Direction.Positive;
},
value => value ? Direction.Positive : Direction.Negative))
: base(DirectionToBoolBiconverter)
{
foreach (T item in items)
Add(item, Direction.Positive);
Expand All @@ -65,14 +60,8 @@ public DirectionCollection(params T[] items)
/// Initializes a new instance of this type.
/// </summary>
public DirectionCollection()
: base(new Biconverter<Direction, bool>(
value => {
if (value==Direction.None)
throw Exceptions.InvalidArgument(value, "value");
return value==Direction.Positive;
},
value => value ? Direction.Positive : Direction.Negative))
: base(DirectionToBoolBiconverter)
{
}
}
}
}
Loading