Skip to content

Commit c578c41

Browse files
committed
Optimize Visitors (#105)
* Optimize Visitors * Memoize GetGenericTypeDefinition() * Revert Memoizing MakeDelegateType()
1 parent cc0cb81 commit c578c41

20 files changed

Lines changed: 218 additions & 198 deletions

File tree

.editorconfig

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ indent_style = space
3535
tab_width = 2
3636

3737
# New line preferences
38-
end_of_line = crlf
38+
end_of_line = lf
3939
insert_final_newline = false
4040

4141
#### .NET Coding Conventions ####

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

Lines changed: 31 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ public static Expression Visit(Expression exp, Func<T, Expression> visitor)
3030

3131
protected override Expression Visit(Expression exp)
3232
{
33-
if (exp is T && visitor!=null)
33+
if (exp is T && visitor != null)
3434
exp = visitor((T) exp);
3535

3636
return base.Visit(exp);
@@ -54,7 +54,7 @@ internal abstract class ExpressionVisitor
5454

5555
protected virtual Expression Visit(Expression exp)
5656
{
57-
if (exp==null)
57+
if (exp == null)
5858
return null;
5959
switch (exp.NodeType) {
6060
case ExpressionType.Negate:
@@ -127,8 +127,8 @@ private Expression VisitBinary(BinaryExpression b)
127127
Expression left = Visit(b.Left);
128128
Expression right = Visit(b.Right);
129129
Expression conversion = Visit(b.Conversion);
130-
if (left!=b.Left || right!=b.Right || conversion!=b.Conversion) {
131-
if (b.NodeType==ExpressionType.Coalesce)
130+
if (left != b.Left || right != b.Right || conversion != b.Conversion) {
131+
if (b.NodeType == ExpressionType.Coalesce)
132132
return Expression.Coalesce(left, right, conversion as LambdaExpression);
133133
return Expression.MakeBinary(b.NodeType, left, right, b.IsLiftedToNull, b.Method);
134134
}
@@ -154,16 +154,16 @@ private IEnumerable<MemberBinding> VisitBindingList(ReadOnlyCollection<MemberBin
154154
List<MemberBinding> list = null;
155155
for (int i = 0, n = original.Count; i < n; i++) {
156156
MemberBinding b = VisitBinding(original[i]);
157-
if (list!=null)
157+
if (list != null)
158158
list.Add(b);
159-
else if (b!=original[i]) {
159+
else if (b != original[i]) {
160160
list = new List<MemberBinding>(n);
161161
for (int j = 0; j < i; j++)
162162
list.Add(original[j]);
163163
list.Add(b);
164164
}
165165
}
166-
if (list!=null)
166+
if (list != null)
167167
return list;
168168
return original;
169169
}
@@ -173,7 +173,7 @@ private Expression VisitConditional(ConditionalExpression c)
173173
Expression test = Visit(c.Test);
174174
Expression ifTrue = Visit(c.IfTrue);
175175
Expression ifFalse = Visit(c.IfFalse);
176-
if (test!=c.Test || ifTrue!=c.IfTrue || ifFalse!=c.IfFalse)
176+
if (test != c.Test || ifTrue != c.IfTrue || ifFalse != c.IfFalse)
177177
return Expression.Condition(test, ifTrue, ifFalse);
178178
return c;
179179
}
@@ -191,7 +191,7 @@ private Expression VisitDefault(DefaultExpression d)
191191
private ElementInit VisitElementInitializer(ElementInit initializer)
192192
{
193193
IEnumerable<Expression> arguments = VisitExpressionList(initializer.Arguments);
194-
if (arguments!=initializer.Arguments)
194+
if (arguments != initializer.Arguments)
195195
return Expression.ElementInit(initializer.AddMethod, arguments);
196196
return initializer;
197197
}
@@ -201,16 +201,16 @@ private IEnumerable<ElementInit> VisitElementInitializerList(ReadOnlyCollection<
201201
List<ElementInit> list = null;
202202
for (int i = 0, n = original.Count; i < n; i++) {
203203
ElementInit init = VisitElementInitializer(original[i]);
204-
if (list!=null)
204+
if (list != null)
205205
list.Add(init);
206-
else if (init!=original[i]) {
206+
else if (init != original[i]) {
207207
list = new List<ElementInit>(n);
208208
for (int j = 0; j < i; j++)
209209
list.Add(original[j]);
210210
list.Add(init);
211211
}
212212
}
213-
if (list!=null)
213+
if (list != null)
214214
return list;
215215
return original;
216216
}
@@ -220,16 +220,16 @@ private IEnumerable<Expression> VisitExpressionList(ReadOnlyCollection<Expressio
220220
List<Expression> list = null;
221221
for (int i = 0, n = original.Count; i < n; i++) {
222222
var p = Visit(original[i]);
223-
if (list!=null)
223+
if (list != null)
224224
list.Add(p);
225-
else if (p!=original[i]) {
225+
else if (p != original[i]) {
226226
list = new List<Expression>(n);
227227
for (int j = 0; j < i; j++)
228228
list.Add(original[j]);
229229
list.Add(p);
230230
}
231231
}
232-
if (list!=null)
232+
if (list != null)
233233
return list.AsReadOnly();
234234
return original;
235235
}
@@ -238,15 +238,15 @@ private Expression VisitInvocation(InvocationExpression iv)
238238
{
239239
IEnumerable<Expression> args = VisitExpressionList(iv.Arguments);
240240
Expression expr = Visit(iv.Expression);
241-
if (args!=iv.Arguments || expr!=iv.Expression)
241+
if (args != iv.Arguments || expr != iv.Expression)
242242
return Expression.Invoke(expr, args);
243243
return iv;
244244
}
245245

246246
private Expression VisitLambda(LambdaExpression lambda)
247247
{
248248
Expression body = Visit(lambda.Body);
249-
if (body!=lambda.Body)
249+
if (body != lambda.Body)
250250
return FastExpression.Lambda(lambda.Type, body, lambda.Parameters);
251251
return lambda;
252252
}
@@ -255,23 +255,24 @@ private Expression VisitListInit(ListInitExpression init)
255255
{
256256
NewExpression n = VisitNew(init.NewExpression);
257257
IEnumerable<ElementInit> initializers = VisitElementInitializerList(init.Initializers);
258-
if (n!=init.NewExpression || initializers!=init.Initializers)
258+
if (n != init.NewExpression || initializers != init.Initializers)
259259
return Expression.ListInit(n, initializers);
260260
return init;
261261
}
262262

263263
private Expression VisitMemberAccess(MemberExpression m)
264264
{
265-
Expression exp = Visit(m.Expression);
266-
if (exp!=m.Expression)
265+
var originalExpression = m.Expression;
266+
Expression exp = Visit(originalExpression);
267+
if (exp != originalExpression)
267268
return Expression.MakeMemberAccess(exp, m.Member);
268269
return m;
269270
}
270271

271272
private MemberAssignment VisitMemberAssignment(MemberAssignment assignment)
272273
{
273274
Expression e = Visit(assignment.Expression);
274-
if (e!=assignment.Expression)
275+
if (e != assignment.Expression)
275276
return Expression.Bind(assignment.Member, e);
276277
return assignment;
277278
}
@@ -280,23 +281,23 @@ private Expression VisitMemberInit(MemberInitExpression init)
280281
{
281282
NewExpression n = VisitNew(init.NewExpression);
282283
IEnumerable<MemberBinding> bindings = VisitBindingList(init.Bindings);
283-
if (n!=init.NewExpression || bindings!=init.Bindings)
284+
if (n != init.NewExpression || bindings != init.Bindings)
284285
return Expression.MemberInit(n, bindings);
285286
return init;
286287
}
287288

288289
private MemberListBinding VisitMemberListBinding(MemberListBinding binding)
289290
{
290291
IEnumerable<ElementInit> initializers = VisitElementInitializerList(binding.Initializers);
291-
if (initializers!=binding.Initializers)
292+
if (initializers != binding.Initializers)
292293
return Expression.ListBind(binding.Member, initializers);
293294
return binding;
294295
}
295296

296297
private MemberMemberBinding VisitMemberMemberBinding(MemberMemberBinding binding)
297298
{
298299
IEnumerable<MemberBinding> bindings = VisitBindingList(binding.Bindings);
299-
if (bindings!=binding.Bindings)
300+
if (bindings != binding.Bindings)
300301
return Expression.MemberBind(binding.Member, bindings);
301302
return binding;
302303
}
@@ -305,24 +306,24 @@ private Expression VisitMethodCall(MethodCallExpression m)
305306
{
306307
Expression obj = Visit(m.Object);
307308
IEnumerable<Expression> args = VisitExpressionList(m.Arguments);
308-
if (obj!=m.Object || args!=m.Arguments)
309+
if (obj != m.Object || args != m.Arguments)
309310
return Expression.Call(obj, m.Method, args);
310311
return m;
311312
}
312313

313314
private NewExpression VisitNew(NewExpression nex)
314315
{
315316
IEnumerable<Expression> args = VisitExpressionList(nex.Arguments);
316-
if (args!=nex.Arguments)
317+
if (args != nex.Arguments)
317318
return Expression.New(nex.Constructor, args, nex.Members);
318319
return nex;
319320
}
320321

321322
private Expression VisitNewArray(NewArrayExpression na)
322323
{
323324
IEnumerable<Expression> exprs = VisitExpressionList(na.Expressions);
324-
if (exprs!=na.Expressions) {
325-
if (na.NodeType==ExpressionType.NewArrayInit)
325+
if (exprs != na.Expressions) {
326+
if (na.NodeType == ExpressionType.NewArrayInit)
326327
return Expression.NewArrayInit(na.Type.GetElementType(), exprs);
327328
return Expression.NewArrayBounds(na.Type.GetElementType(), exprs);
328329
}
@@ -337,15 +338,15 @@ private Expression VisitParameter(ParameterExpression p)
337338
private Expression VisitTypeIs(TypeBinaryExpression b)
338339
{
339340
Expression expr = Visit(b.Expression);
340-
if (expr!=b.Expression)
341+
if (expr != b.Expression)
341342
return Expression.TypeIs(expr, b.TypeOperand);
342343
return b;
343344
}
344345

345346
private Expression VisitUnary(UnaryExpression u)
346347
{
347348
Expression operand = Visit(u.Operand);
348-
if (operand!=u.Operand)
349+
if (operand != u.Operand)
349350
return Expression.MakeUnary(u.NodeType, operand, u.Type, u.Method);
350351
return u;
351352
}

Orm/Xtensive.Orm.Tests.Core/Reflection/TypeHelperTest.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -349,7 +349,7 @@ public void GetNameAndAddSuffixTest()
349349
sName = t.GetShortName();
350350
Assert.AreEqual("A<Int32,String>+B<Boolean>", sName);
351351

352-
t = t.GetGenericTypeDefinition().GetGenericArguments()[2];
352+
t = t.CachedGetGenericTypeDefinition().GetGenericArguments()[2];
353353
fName = t.GetFullName();
354354
Assert.AreEqual("T3", fName);
355355
sName = t.GetShortName();

Orm/Xtensive.Orm.Tests.Framework/Dynamic.cs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
//Copyright (C) Microsoft Corporation. All rights reserved.
1+
//Copyright (C) Microsoft Corporation. All rights reserved.
22

33
using System.Collections.Generic;
44
using System.Globalization;
@@ -7,6 +7,7 @@
77
using System.Reflection.Emit;
88
using System.Text;
99
using System.Threading;
10+
using Xtensive.Reflection;
1011

1112
namespace System.Linq.Dynamic
1213
{
@@ -1309,7 +1310,7 @@ private static Type FindGenericType(Type generic, Type type)
13091310
{
13101311
while (type != null && type != typeof (object))
13111312
{
1312-
if (type.IsGenericType && type.GetGenericTypeDefinition() == generic) return type;
1313+
if (type.IsGenericType && type.CachedGetGenericTypeDefinition() == generic) return type;
13131314
if (generic.IsInterface)
13141315
{
13151316
foreach (Type intfType in type.GetInterfaces())
@@ -1417,7 +1418,7 @@ private static bool IsPredefinedType(Type type)
14171418

14181419
private static bool IsNullableType(Type type)
14191420
{
1420-
return type.IsGenericType && type.GetGenericTypeDefinition() == typeof (Nullable<>);
1421+
return type.IsGenericType && type.CachedGetGenericTypeDefinition() == typeof (Nullable<>);
14211422
}
14221423

14231424
private static Type GetNonNullableType(Type type)

Orm/Xtensive.Orm.Tests/Linq/MemberCompilerProviderTest.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -147,7 +147,7 @@ public void ArrayAndEnumerableOverloadTest()
147147
var eachEnumerable = typeof (EachExtensions)
148148
.GetMethods()
149149
.Single(method => method.GetParameterTypes()
150-
.Any(type => type.IsGenericType && type.GetGenericTypeDefinition()==typeof(IEnumerable<>)))
150+
.Any(type => type.IsGenericType && type.CachedGetGenericTypeDefinition()==typeof(IEnumerable<>)))
151151
.MakeGenericMethod(typeof (int));
152152
var eachEnumerableCompiler = provider.GetCompiler(eachEnumerable);
153153
Assert.AreEqual("EachInEnumerable", eachEnumerableCompiler.Invoke(null, dummy));

Orm/Xtensive.Orm.Tests/Linq/QueryDumper.cs

Lines changed: 21 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -228,20 +228,20 @@ private void CreateNodeTree(List<object> values, ref XmlDocument document, strin
228228
var depth = 1;
229229
XmlNode itemNode = document.CreateElement("Item" + itemIndex);
230230

231-
if (value==null || !value.GetType().IsGenericType || (value.GetType().IsGenericType && value.GetType().GetGenericTypeDefinition()!=typeof (Grouping<,>))) {
231+
if (value == null || !value.GetType().IsGenericType || (value.GetType().IsGenericType && value.GetType().CachedGetGenericTypeDefinition() != typeof(Grouping<,>))) {
232232
itemNode = document.CreateElement("Item" + itemIndex);
233233
itemIndex++;
234234
parentNode.AppendChild(itemNode);
235235
}
236236

237237
if (value==null || ((GetMemberType(value.GetType())==MemberType.Primitive
238238
|| GetMemberType(value.GetType())==MemberType.Unknown) && !value.GetType().IsGenericType)
239-
|| (value.GetType().IsGenericType && value.GetType().GetGenericTypeDefinition()!=typeof (Grouping<,>))
239+
|| (value.GetType().IsGenericType && value.GetType().CachedGetGenericTypeDefinition()!=typeof (Grouping<,>))
240240
&& (GetMemberType(value.GetType())==MemberType.Primitive
241241
|| GetMemberType(value.GetType())==MemberType.Unknown))
242242
depth = AddNode(value, null, ref document, itemNode, depth);
243243

244-
else if (value.GetType().IsGenericType && value.GetType().GetGenericTypeDefinition()==typeof (Grouping<,>)) {
244+
else if (value.GetType().IsGenericType && value.GetType().CachedGetGenericTypeDefinition()==typeof (Grouping<,>)) {
245245
var exactValue = (IEnumerable) value;
246246
foreach (var val in exactValue) {
247247
itemNode = document.CreateElement("Item" + itemIndex);
@@ -299,8 +299,8 @@ private int AddNode(object value, PropertyInfo property, ref XmlDocument documen
299299

300300
else {
301301
if (property.PropertyType.IsGenericType &&
302-
(property.PropertyType.GetGenericTypeDefinition()==typeof (IQueryable<>)
303-
|| (property.PropertyType.GetGenericTypeDefinition()==typeof (IEnumerable<>)))) {
302+
(property.PropertyType.CachedGetGenericTypeDefinition() == typeof(IQueryable<>)
303+
|| (property.PropertyType.CachedGetGenericTypeDefinition() == typeof(IEnumerable<>)))) {
304304
var enumerable = (IEnumerable) property.GetValue(value, property.GetIndexParameters());
305305
var list = new List<object>();
306306
foreach (var o in enumerable)
@@ -556,19 +556,24 @@ private string KeyToString(object key)
556556
private static void EnumerateAll(IEnumerable enumerable)
557557
{
558558
foreach (var o in enumerable)
559-
if (o!=null) {
560-
if (o.GetType().IsGenericType && (o.GetType().GetGenericTypeDefinition()==typeof (IQueryable<>)
561-
|| o.GetType().GetGenericTypeDefinition()==typeof (IEnumerable<>)
562-
|| o.GetType().GetGenericTypeDefinition()==typeof (SubQuery<>)
563-
|| o.GetType().GetGenericTypeDefinition()==typeof (Grouping<,>)))
564-
EnumerateAll((IEnumerable) o);
565-
var properties = o.GetType().GetProperties();
559+
if (o != null) {
560+
var type = o.GetType();
561+
if (type.IsGenericType) {
562+
var genericTypeDefinition = type.CachedGetGenericTypeDefinition();
563+
if (genericTypeDefinition == typeof(IQueryable<>)
564+
|| genericTypeDefinition == typeof(IEnumerable<>)
565+
|| genericTypeDefinition == typeof(SubQuery<>)
566+
|| genericTypeDefinition == typeof(Grouping<,>)) {
567+
EnumerateAll((IEnumerable) o);
568+
}
569+
}
570+
var properties = type.GetProperties();
566571
foreach (var info in properties) {
567572
if (info.PropertyType.IsGenericType &&
568-
(info.PropertyType.GetGenericTypeDefinition()==typeof (IQueryable<>)
569-
|| info.PropertyType.GetGenericTypeDefinition()==typeof (IEnumerable<>)
570-
|| info.PropertyType.GetGenericTypeDefinition()==typeof (SubQuery<>)
571-
|| info.PropertyType.GetGenericTypeDefinition()==typeof (Grouping<,>)
573+
(info.PropertyType.CachedGetGenericTypeDefinition()==typeof (IQueryable<>)
574+
|| info.PropertyType.CachedGetGenericTypeDefinition()==typeof (IEnumerable<>)
575+
|| info.PropertyType.CachedGetGenericTypeDefinition()==typeof (SubQuery<>)
576+
|| info.PropertyType.CachedGetGenericTypeDefinition()==typeof (Grouping<,>)
572577
))
573578
EnumerateAll((IEnumerable) info.GetValue(o, null));
574579
}

Orm/Xtensive.Orm/Orm/Building/Builders/TypeBuilder.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -417,7 +417,7 @@ private static bool IsAuxiliaryType(TypeInfo type)
417417
var underlyingBaseType = type.UnderlyingType.BaseType;
418418
return underlyingBaseType != null
419419
&& underlyingBaseType.IsGenericType
420-
&& underlyingBaseType.GetGenericTypeDefinition() == WellKnownOrmTypes.EntitySetItemOfT1T2;
420+
&& underlyingBaseType.CachedGetGenericTypeDefinition() == WellKnownOrmTypes.EntitySetItemOfT1T2;
421421
}
422422

423423
private ColumnInfo BuildDeclaredColumn(FieldInfo field)

Orm/Xtensive.Orm/Orm/Building/Builders/ValueTypeBuilder.cs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -61,14 +61,16 @@ private static object AdjustValue(string fieldName, Type fieldType, object value
6161
#if NET6_0_OR_GREATER
6262

6363
if (valueType == WellKnownTypes.TimeOnly) {
64-
if (value is string timeOnlyString && !TimeOnly.TryParse(timeOnlyString, out var timeOnly)) {
64+
TimeOnly timeOnly = default;
65+
if (value is string timeOnlyString && !TimeOnly.TryParse(timeOnlyString, out timeOnly)) {
6566
throw FailToParseValue(fieldName, timeOnlyString);
6667
}
6768
return timeOnly;
6869
}
6970

7071
if (valueType == WellKnownTypes.DateOnly) {
71-
if (value is string dateOnlyString && !DateOnly.TryParse(dateOnlyString, out var dateOnly)) {
72+
DateOnly dateOnly = default;
73+
if (value is string dateOnlyString && !DateOnly.TryParse(dateOnlyString, out dateOnly)) {
7274
throw FailToParseValue(fieldName, dateOnlyString);
7375
}
7476
return dateOnly;

0 commit comments

Comments
 (0)