Skip to content

Commit 47e8b98

Browse files
committed
Optimize Build Domain operation
Optimize GetAttributes Refactoring: get rid of dictionaries in TypeInfoCollection Debug BuildFilds() Use TypeHelper.GetInterfaces() to avoid multiple allocations Memoize GetProperties() Make TupleDescriptor readonly struct Refactor to IReadOnlyList<> where possible Optimize PrefetchActionContainer Make Edge readonly struct Avoid O(n^2) complexity in types topological sorting Optimize IndexBuilder Improve NodeCollection Optimize ExpressionProcessor LockableBase.EnsureNotLocked() for efficiency Improve TypeDef Optimize InterfaceMapping Optimize VersionColumns, VersionFields
1 parent f9d4d0f commit 47e8b98

81 files changed

Lines changed: 940 additions & 1082 deletions

File tree

Some content is hidden

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

Orm/Xtensive.Orm.Tests.Core/DotNetFramework/NewTupleLogicTest.cs

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -145,12 +145,18 @@ public void PeformanceTest()
145145

146146
private void Test(int count)
147147
{
148-
using (warmup ? new Disposable(delegate { }) :
149-
TestLog.InfoRegion("With boxing"))
148+
if (warmup) {
150149
TestTupleAccess(new BoxingTuple(), count);
151-
using (warmup ? new Disposable(delegate { }) :
152-
TestLog.InfoRegion("Without boxing"))
153150
TestTupleAccess(new NonBoxingTuple(), count);
151+
}
152+
else {
153+
using (TestLog.InfoRegion("With boxing")) {
154+
TestTupleAccess(new BoxingTuple(), count);
155+
}
156+
using (TestLog.InfoRegion("Without boxing")) {
157+
TestTupleAccess(new NonBoxingTuple(), count);
158+
}
159+
}
154160
}
155161

156162
private void TestTupleAccess(TestTuple tuple, int count)

Orm/Xtensive.Orm.Tests.Core/DotNetFramework/ThreadingTest.cs

Lines changed: 24 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -219,13 +219,24 @@ private void LockTest(double speedFactor, int threadCount)
219219
passCountBase /= 10;
220220

221221
TestHelper.CollectGarbage();
222-
using (warmup ? null : TestLog.InfoRegion(string.Format("{0} threads", threadCount))) {
223-
ThreadedTest(target, passCountBase, target.ExecuteLock);
224-
ThreadedTest(target, passCountBase, target.ExecuteReadLock);
225-
ThreadedTest(target, passCountBase, target.ExecuteWriteLock);
226-
if (threadCount>1) {
227-
ThreadedTest(target, passCountBase / 200, target.ExecuteWaitLock);
228-
ThreadedTest(target, passCountBase / 400, target.ExecuteSleepLock);
222+
if (warmup) {
223+
ThreadedTest(target, passCountBase, target.ExecuteLock);
224+
ThreadedTest(target, passCountBase, target.ExecuteReadLock);
225+
ThreadedTest(target, passCountBase, target.ExecuteWriteLock);
226+
if (threadCount>1) {
227+
ThreadedTest(target, passCountBase / 200, target.ExecuteWaitLock);
228+
ThreadedTest(target, passCountBase / 400, target.ExecuteSleepLock);
229+
}
230+
}
231+
else {
232+
using (TestLog.InfoRegion(string.Format("{0} threads", threadCount))) {
233+
ThreadedTest(target, passCountBase, target.ExecuteLock);
234+
ThreadedTest(target, passCountBase, target.ExecuteReadLock);
235+
ThreadedTest(target, passCountBase, target.ExecuteWriteLock);
236+
if (threadCount>1) {
237+
ThreadedTest(target, passCountBase / 200, target.ExecuteWaitLock);
238+
ThreadedTest(target, passCountBase / 400, target.ExecuteSleepLock);
239+
}
229240
}
230241
}
231242
}
@@ -240,9 +251,14 @@ private void InvokeAsyncTest(double speedFactor, int threadCount)
240251
passCountBase /= 10;
241252

242253
TestHelper.CollectGarbage();
243-
using (warmup ? null : TestLog.InfoRegion(string.Format("{0} threads", threadCount))) {
254+
if (warmup) {
244255
ThreadedTest(target, passCountBase/100, target.ExecuteInvokeAsync);
245256
}
257+
else {
258+
using (TestLog.InfoRegion(string.Format("{0} threads", threadCount))) {
259+
ThreadedTest(target, passCountBase/100, target.ExecuteInvokeAsync);
260+
}
261+
}
246262
}
247263

248264
private static void ThreadedTest(Target target, int passCount, ParameterizedThreadStart method)

Orm/Xtensive.Orm.Tests.Core/Helpers/TopologicalSorterTest.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ private static void InternalPerformanceTest(int nodeCount, int averageConnection
6363
List<Node<int, int>> removedEdges;
6464
var result = TopologicalSorter.Sort(nodes, out removedEdges);
6565
if (!allowLoops)
66-
Assert.AreEqual(nodeCount, result.Count);
66+
Assert.AreEqual(nodeCount, result.Count());
6767
}
6868
GC.GetTotalMemory(true);
6969
}
@@ -132,7 +132,7 @@ public void CombinedTest()
132132
private void TestSort<T>(T[] data, Predicate<T, T> connector, T[] expected, T[] loops)
133133
{
134134
List<Node<T, object>> actualLoopNodes;
135-
List<T> actual = TopologicalSorter.Sort(data, connector, out actualLoopNodes);
135+
List<T> actual = TopologicalSorter.Sort(data, connector, out actualLoopNodes).ToList();
136136
T[] actualLoops = null;
137137
if (actualLoopNodes != null)
138138
actualLoops = actualLoopNodes

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,7 @@ public void CombinedTest()
117117
desc = TestDescriptor(desc, new Type[] {typeof(bool?), typeof(bool), typeof(bool?)});
118118
}
119119

120-
private TupleDescriptor TestDescriptor(TupleDescriptor theSame, Type[] types)
120+
private TupleDescriptor TestDescriptor(TupleDescriptor? theSame, Type[] types)
121121
{
122122
var d1 = TupleDescriptor.Create(types);
123123
var d2 = TupleDescriptor.Create(types);

Orm/Xtensive.Orm.Tests.Framework/DomainModelExtensions.cs

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ public static void Dump(this TypeInfoCollection target)
8181

8282
public static void DumpAncestor(this TypeInfo target, int indent)
8383
{
84-
TypeInfo ancestor = target.GetAncestor();
84+
TypeInfo ancestor = target.Ancestor;
8585
if (ancestor!=null)
8686
WriteLine(indent + 1, "Ancestor: " + ancestor.Name);
8787
else {
@@ -92,8 +92,8 @@ public static void DumpAncestor(this TypeInfo target, int indent)
9292
public static void DumpDescendants(this TypeInfo target, int indent)
9393
{
9494
WriteLine(indent, "Descendants:");
95-
HashSet<TypeInfo> direct = new HashSet<TypeInfo>(target.GetDescendants());
96-
foreach (TypeInfo descendant in target.GetDescendants(true)) {
95+
var direct = target.Descendants;
96+
foreach (TypeInfo descendant in target.RecursiveDescendants) {
9797
if (direct.Contains(descendant))
9898
WriteLine(indent + 1, descendant.Name + " (direct)");
9999
else
@@ -104,8 +104,8 @@ public static void DumpDescendants(this TypeInfo target, int indent)
104104
public static void DumpInterfaces(this TypeInfo target, int indent)
105105
{
106106
WriteLine(indent, "Interfaces:");
107-
HashSet<TypeInfo> direct = new HashSet<TypeInfo>(target.GetInterfaces());
108-
foreach (TypeInfo @interface in target.GetInterfaces(true)) {
107+
var direct = target.Interfaces;
108+
foreach (TypeInfo @interface in target.RecursiveInterfaces) {
109109
if (direct.Contains(@interface))
110110
WriteLine(indent + 1, @interface.Name + " (direct)");
111111
else
@@ -116,8 +116,8 @@ public static void DumpInterfaces(this TypeInfo target, int indent)
116116
public static void DumpImplementors(this TypeInfo target, int indent)
117117
{
118118
WriteLine(indent, "Implementors:");
119-
HashSet<TypeInfo> direct = new HashSet<TypeInfo>(target.GetImplementors());
120-
foreach (TypeInfo implementor in target.GetImplementors(true)) {
119+
var direct = target.Implementors;
120+
foreach (TypeInfo implementor in target.RecursiveImplementors) {
121121
if (direct.Contains(implementor))
122122
WriteLine(indent + 1, implementor.Name + " (direct)");
123123
else
@@ -163,10 +163,10 @@ public static void Dump(this TypeInfo target, int indent)
163163
if (target.IsEntity) {
164164
WriteLine(indent, "Hierarchy: " + target.Hierarchy.Root.Name);
165165
if (target.Hierarchy.Root!=target)
166-
WriteLine(indent, "Ancestor: " + target.GetAncestor().Name);
166+
WriteLine(indent, "Ancestor: " + target.Ancestor.Name);
167167
}
168168
else if (target.IsInterface) {
169-
WriteLine(indent, "Implementors: " + target.GetImplementors().Select(t => t.Name).ToCommaDelimitedString());
169+
WriteLine(indent, "Implementors: " + target.Implementors.Select(t => t.Name).ToCommaDelimitedString());
170170
}
171171

172172
target.DumpMappingName(indent);

Orm/Xtensive.Orm.Tests/Issues/IssueJira0117_FKStructureTest.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,7 @@ protected override DomainConfiguration BuildConfiguration()
9696
public void AssociationThroughStructureTest()
9797
{
9898
var type = Domain.Model.Types[typeof (Owner1)];
99-
Assert.AreEqual(2, type.GetOwnerAssociations().Count);
99+
Assert.AreEqual(2, type.GetOwnerAssociations().Count());
100100
Assert.AreEqual(8, Domain.Model.Associations.Count);
101101
}
102102

Orm/Xtensive.Orm.Tests/Model/LibraryTest.cs

Lines changed: 10 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -393,34 +393,29 @@ protected override DomainConfiguration BuildConfiguration()
393393
private static void VerifyModel(Domain domain)
394394
{
395395
TypeInfoCollection types = domain.Model.Types;
396-
Assert.AreEqual(types.FindAncestor(types[typeof (Person)]), null);
397-
Assert.AreEqual(types.FindAncestor(types[typeof (Book)]), null);
398-
Assert.AreEqual(types.FindAncestor(types[typeof (BookReview)]), null);
399-
Assert.AreEqual(types.FindAncestor(types[typeof (Author)]), types[typeof (Person)]);
400-
401-
Assert.AreEqual(types[typeof (Person)].GetAncestor(), null);
402-
Assert.AreEqual(types[typeof (Book)].GetAncestor(), null);
403-
Assert.AreEqual(types[typeof (BookReview)].GetAncestor(), null);
404-
Assert.AreEqual(types[typeof (Author)].GetAncestor(), types[typeof (Person)]);
396+
Assert.AreEqual(types[typeof (Person)].Ancestor, null);
397+
Assert.AreEqual(types[typeof (Book)].Ancestor, null);
398+
Assert.AreEqual(types[typeof (BookReview)].Ancestor, null);
399+
Assert.AreEqual(types[typeof (Author)].Ancestor, types[typeof (Person)]);
405400

406-
ICollection<TypeInfo> collection = types.Structures;
407-
Assert.IsTrue(collection.Count > 0);
401+
var collection = types.Structures;
402+
Assert.IsTrue(collection.Any());
408403
foreach (TypeInfo item in collection) {
409404
Assert.IsTrue(item.IsStructure);
410405
Assert.IsFalse(item.IsInterface);
411406
Assert.IsFalse(item.IsEntity);
412407
}
413408

414409
collection = types.Interfaces;
415-
Assert.IsFalse(collection.Count > 0);
410+
Assert.IsFalse(collection.Any());
416411
foreach (TypeInfo item in collection) {
417412
Assert.IsTrue(item.IsInterface);
418413
Assert.IsFalse(item.IsStructure);
419414
Assert.IsFalse(item.IsEntity);
420415
}
421416

422417
collection = types.Entities;
423-
Assert.IsTrue(collection.Count > 0);
418+
Assert.IsTrue(collection.Any());
424419
foreach (TypeInfo item in collection) {
425420
Assert.IsTrue(item.IsEntity);
426421
Assert.IsFalse(item.IsInterface);
@@ -555,8 +550,8 @@ private static void VerifyModel(Domain domain)
555550
Assert.AreEqual(true, typeInfo.Fields["Books"].IsNullable);
556551
Assert.AreEqual("Books", typeInfo.Fields["Books"].Name);
557552

558-
Assert.AreEqual(2, typeInfo.Fields.Find(FieldAttributes.Declared).Count);
559-
Assert.AreEqual(9, typeInfo.Fields.Find(FieldAttributes.Inherited).Count);
553+
Assert.AreEqual(2, typeInfo.Fields.Find(FieldAttributes.Declared).Count());
554+
Assert.AreEqual(9, typeInfo.Fields.Find(FieldAttributes.Inherited).Count());
560555

561556
// KeyColumns
562557
Assert.IsNotNull(typeInfo.Columns["PassportNumber"]);

Orm/Xtensive.Orm.Tests/Storage/Prefetch/PrefetchTestHelper.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -41,9 +41,9 @@ public static void AssertOnlySpecifiedColumnsAreLoaded(Key key, TypeInfo type, S
4141
{
4242
var state = session.EntityStateCache[key, true];
4343
var realType = state.Key.TypeInfo;
44-
Assert.IsTrue(realType.Equals(type)
45-
|| realType.GetAncestors().Contains(type)
46-
|| (type.IsInterface && realType.GetInterfaces(true).Contains(type)));
44+
Assert.IsTrue(realType.Equals(type)
45+
|| realType.Ancestors.Contains(type)
46+
|| (type.IsInterface && realType.RecursiveInterfaces.Contains(type)));
4747
var tuple = state.Tuple;
4848
Assert.IsNotNull(tuple);
4949
foreach (var field in type.Fields) {

Orm/Xtensive.Orm.Tests/Storage/VersionBehaviorTest.cs

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
// Created: 2010.08.05
66

77
using System;
8+
using System.Linq;
89
using System.Diagnostics;
910
using NUnit.Framework;
1011
using Xtensive.Orm.Tests;
@@ -186,8 +187,8 @@ public void DefaultTest()
186187
var domain = Domain.Build(config);
187188
var defaultTypeInfo = domain.Model.Types[typeof(Default)];
188189
var defaultInheritorTypeInfo = domain.Model.Types[typeof(DefaultInheritor)];
189-
Assert.AreEqual(3, defaultTypeInfo.GetVersionColumns().Count);
190-
Assert.AreEqual(4, defaultInheritorTypeInfo.GetVersionColumns().Count);
190+
Assert.AreEqual(3, defaultTypeInfo.GetVersionColumns().Count());
191+
Assert.AreEqual(4, defaultInheritorTypeInfo.GetVersionColumns().Count());
191192
using (var session = domain.OpenSession()) {
192193
var versions = new VersionSet();
193194
var updatedVersions = new VersionSet();
@@ -256,10 +257,10 @@ public void ManualTest()
256257
var anotherManualTypeInfo = domain.Model.Types[typeof(AnotherManual)];
257258
var manualInheritorTypeInfo = domain.Model.Types[typeof(ManualInheritor)];
258259
var anotherManualInheritorTypeInfo = domain.Model.Types[typeof(AnotherManualInheritor)];
259-
Assert.AreEqual(1, manualTypeInfo.GetVersionColumns().Count);
260-
Assert.AreEqual(2, anotherManualTypeInfo.GetVersionColumns().Count);
261-
Assert.AreEqual(1, manualInheritorTypeInfo.GetVersionColumns().Count);
262-
Assert.AreEqual(2, anotherManualInheritorTypeInfo.GetVersionColumns().Count);
260+
Assert.AreEqual(1, manualTypeInfo.GetVersionColumns().Count());
261+
Assert.AreEqual(2, anotherManualTypeInfo.GetVersionColumns().Count());
262+
Assert.AreEqual(1, manualInheritorTypeInfo.GetVersionColumns().Count());
263+
Assert.AreEqual(2, anotherManualInheritorTypeInfo.GetVersionColumns().Count());
263264
using (var session = domain.OpenSession()) {
264265
var versions = new VersionSet();
265266
var updatedVersions = new VersionSet();
@@ -322,8 +323,8 @@ public void AutoTest()
322323
var domain = Domain.Build(config);
323324
var autoTypeInfo = domain.Model.Types[typeof(Auto)];
324325
var autoInheritorTypeInfo = domain.Model.Types[typeof(AutoInheritor)];
325-
Assert.AreEqual(1, autoTypeInfo.GetVersionColumns().Count);
326-
Assert.AreEqual(2, autoInheritorTypeInfo.GetVersionColumns().Count);
326+
Assert.AreEqual(1, autoTypeInfo.GetVersionColumns().Count());
327+
Assert.AreEqual(2, autoInheritorTypeInfo.GetVersionColumns().Count());
327328
using (var session = domain.OpenSession()) {
328329
var versions = new VersionSet();
329330
var updatedVersions = new VersionSet();
@@ -400,9 +401,9 @@ public void SkipTest()
400401
var skipTypeInfo = domain.Model.Types[typeof(Skip)];
401402
var hasVersionTypeInfo = domain.Model.Types[typeof(HasVersion)];
402403
var hasSkipVersionTypeInfo = domain.Model.Types[typeof(HasSkipVersion)];
403-
Assert.AreEqual(2, skipTypeInfo.GetVersionColumns().Count);
404-
Assert.AreEqual(2, hasVersionTypeInfo.GetVersionColumns().Count);
405-
Assert.AreEqual(2, hasSkipVersionTypeInfo.GetVersionColumns().Count);
404+
Assert.AreEqual(2, skipTypeInfo.GetVersionColumns().Count());
405+
Assert.AreEqual(2, hasVersionTypeInfo.GetVersionColumns().Count());
406+
Assert.AreEqual(2, hasSkipVersionTypeInfo.GetVersionColumns().Count());
406407
using (var session = domain.OpenSession()) {
407408
var versions = new VersionSet();
408409
var updatedVersions = new VersionSet();

Orm/Xtensive.Orm/Collections/Interfaces/IFilterable.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,14 +21,14 @@ public interface IFilterable<TFilter, TItem>
2121
/// </summary>
2222
/// <param name="criteria">The object to filter initial collection with.</param>
2323
/// <returns><see cref="ICollection{TItem}"/> object.</returns>
24-
ICollection<TItem> Find(TFilter criteria);
24+
IEnumerable<TItem> Find(TFilter criteria);
2525

2626
/// <summary>
2727
/// Finds the items from initial collection according to specified filter <paramref name="criteria"/>.
2828
/// </summary>
2929
/// <param name="criteria">The object to filter initial collection with.</param>
3030
/// <param name="matchType">Type of the match.</param>
3131
/// <returns><see cref="ICollection{TItem}"/> object.</returns>
32-
ICollection<TItem> Find(TFilter criteria, MatchType matchType);
32+
IEnumerable<TItem> Find(TFilter criteria, MatchType matchType);
3333
}
3434
}

0 commit comments

Comments
 (0)