Skip to content

Commit d6f5b8c

Browse files
committed
Improve performance of ExpressionExtensions.MakeTupleAccess method
1 parent 7339ec3 commit d6f5b8c

File tree

1 file changed

+23
-25
lines changed

1 file changed

+23
-25
lines changed

Orm/Xtensive.Orm/Linq/ExpressionExtensions.cs

Lines changed: 23 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
// Created: 2009.04.21
66

77
using System;
8+
using System.Collections.Concurrent;
89
using System.Linq;
910
using System.Linq.Expressions;
1011
using System.Reflection;
@@ -20,7 +21,10 @@ namespace Xtensive.Linq
2021
/// </summary>
2122
public static class ExpressionExtensions
2223
{
23-
private static readonly MethodInfo TupleGenericAccessor;
24+
private static readonly ConcurrentDictionary<Type, MethodInfo> valueAccessors =
25+
new ConcurrentDictionary<Type, MethodInfo>();
26+
27+
private static readonly Func<Type, MethodInfo> TupleValueAccessorFactory;
2428

2529
///<summary>
2630
/// Makes <see cref="Tuples.Tuple.GetValueOrDefault{T}"/> method call.
@@ -29,15 +33,12 @@ public static class ExpressionExtensions
2933
///<param name="accessorType">Type of accessor.</param>
3034
///<param name="index">Tuple field index.</param>
3135
///<returns><see cref="MethodCallExpression"/></returns>
32-
public static MethodCallExpression MakeTupleAccess(this Expression target, Type accessorType, int index)
33-
{
34-
return Expression.Call(
36+
public static MethodCallExpression MakeTupleAccess(this Expression target, Type accessorType, int index) =>
37+
Expression.Call(
3538
target,
36-
TupleGenericAccessor.MakeGenericMethod(accessorType),
39+
valueAccessors.GetOrAdd(accessorType, TupleValueAccessorFactory),
3740
Expression.Constant(index)
38-
);
39-
}
40-
41+
);
4142

4243
/// <summary>
4344
/// Makes <c>IsNull</c> condition expression.
@@ -46,41 +47,38 @@ public static MethodCallExpression MakeTupleAccess(this Expression target, Type
4647
/// <param name="ifNull">Result expression if <paramref name="target"/> is <see langword="null" />.</param>
4748
/// <param name="ifNotNull">Result expression if <paramref name="target"/> is not <see langword="null" />.</param>
4849
/// <returns><see cref="ConditionalExpression"/></returns>
49-
public static ConditionalExpression MakeIsNullCondition(this Expression target, Expression ifNull, Expression ifNotNull)
50-
{
51-
return Expression.Condition(
50+
public static ConditionalExpression MakeIsNullCondition(
51+
this Expression target, Expression ifNull, Expression ifNotNull) =>
52+
Expression.Condition(
5253
Expression.Equal(target, Expression.Constant(null, target.Type)),
53-
ifNull, ifNotNull
54-
);
55-
}
54+
ifNull,
55+
ifNotNull
56+
);
5657

5758
/// <summary>
5859
/// Converts expression type to nullable type (for value types).
5960
/// </summary>
6061
/// <param name="expression">The expression.</param>
61-
public static Expression LiftToNullable(this Expression expression)
62-
{
63-
return expression.Type.IsNullable()
64-
? expression
65-
: Expression.Convert(expression, expression.Type.ToNullable());
66-
}
62+
public static Expression LiftToNullable(this Expression expression) =>
63+
expression.Type.IsNullable()
64+
? expression
65+
: Expression.Convert(expression, expression.Type.ToNullable());
6766

6867
/// <summary>
6968
/// Converts specified <see cref="Expression"/> to <see cref="ExpressionTree"/>.
7069
/// </summary>
7170
/// <param name="expression">The expression to convert.</param>
7271
/// <returns>Expression tree that wraps <paramref name="expression"/>.</returns>
73-
public static ExpressionTree ToExpressionTree(this Expression expression)
74-
{
75-
return new ExpressionTree(expression);
76-
}
72+
public static ExpressionTree ToExpressionTree(this Expression expression) => new ExpressionTree(expression);
7773

7874

7975
// Type initializer
8076

8177
static ExpressionExtensions()
8278
{
83-
TupleGenericAccessor = typeof (Tuple).GetMethods().Single(mi => mi.Name==WellKnown.Tuple.GetValueOrDefault && mi.IsGenericMethod);
79+
var tupleGenericAccessor = typeof(Tuple).GetMethods()
80+
.Single(mi => mi.Name == WellKnown.Tuple.GetValueOrDefault && mi.IsGenericMethod);
81+
TupleValueAccessorFactory = type => tupleGenericAccessor.MakeGenericMethod(type);
8482
}
8583
}
8684
}

0 commit comments

Comments
 (0)