Skip to content

Commit 4c6465b

Browse files
committed
less allocations
1 parent f1e4787 commit 4c6465b

File tree

2 files changed

+24
-18
lines changed

2 files changed

+24
-18
lines changed

src/AutoMapper/Execution/ExpressionBuilder.cs

Lines changed: 18 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,12 @@ public static class ExpressionBuilder
3333
private static readonly MethodInfo CheckContextMethod = typeof(ResolutionContext).GetStaticMethod(nameof(ResolutionContext.CheckContext));
3434
private static readonly MethodInfo ContextMapMethod = typeof(ResolutionContext).GetInstanceMethod(nameof(ResolutionContext.MapInternal));
3535
private static readonly MethodInfo ArrayEmptyMethod = typeof(Array).GetStaticMethod(nameof(Array.Empty));
36+
private static readonly ParameterExpression Disposable = Variable(typeof(IDisposable), "disposableEnumerator");
37+
private static readonly ParameterExpression[] DisposableArray = new[] { Disposable };
38+
private static readonly Expression DisposeCall = IfNullElse(Disposable, Empty, Expression.Call(Disposable, DisposeMethod));
39+
private static readonly ParameterExpression Index = Variable(typeof(int), "sourceArrayIndex");
40+
private static readonly BinaryExpression ResetIndex = Assign(Index, Zero);
41+
private static readonly UnaryExpression IncrementIndex = PostIncrementAssign(Index);
3642

3743
public static Expression MapExpression(this IGlobalConfiguration configurationProvider, ProfileMap profileMap, TypePair typePair, Expression sourceParameter,
3844
MemberMap propertyMap = null, Expression destinationParameter = null)
@@ -262,36 +268,34 @@ public static Expression ForEach(ParameterExpression loopVar, Expression collect
262268
static Expression ForEachArrayItem(ParameterExpression loopVar, Expression array, Expression loopContent)
263269
{
264270
var breakLabel = Label("LoopBreak");
265-
var index = Variable(typeof(int), "sourceArrayIndex");
266-
var loop = Block(new[] { index, loopVar },
267-
Assign(index, Zero),
271+
var loop = Block(new[] { Index, loopVar },
272+
ResetIndex,
268273
Loop(
269274
IfThenElse(
270-
LessThan(index, ArrayLength(array)),
271-
Block(Assign(loopVar, ArrayAccess(array, index)), loopContent, PostIncrementAssign(index)),
275+
LessThan(Index, ArrayLength(array)),
276+
Block(Assign(loopVar, ArrayAccess(array, Index)), loopContent, IncrementIndex),
272277
Break(breakLabel)
273278
),
274279
breakLabel));
275280
return loop;
276281
}
277-
static Expression Using(Expression disposable, Expression body)
282+
static Expression Using(Expression target, Expression body)
278283
{
279-
Expression disposeCall;
280-
if (typeof(IDisposable).IsAssignableFrom(disposable.Type))
284+
Expression finallyDispose;
285+
if (typeof(IDisposable).IsAssignableFrom(target.Type))
281286
{
282-
disposeCall = Expression.Call(disposable, DisposeMethod);
287+
finallyDispose = Expression.Call(target, DisposeMethod);
283288
}
284289
else
285290
{
286-
if (disposable.Type.IsValueType)
291+
if (target.Type.IsValueType)
287292
{
288293
return body;
289294
}
290-
var disposableVariable = Variable(typeof(IDisposable), "disposableVariable");
291-
var assignDisposable = Assign(disposableVariable, TypeAs(disposable, typeof(IDisposable)));
292-
disposeCall = Block(new[] { disposableVariable }, assignDisposable, IfNullElse(disposableVariable, Empty, Expression.Call(disposableVariable, DisposeMethod)));
295+
var assignDisposable = Assign(Disposable, TypeAs(target, typeof(IDisposable)));
296+
finallyDispose = Block(DisposableArray, assignDisposable, DisposeCall);
293297
}
294-
return TryFinally(body, disposeCall);
298+
return TryFinally(body, finallyDispose);
295299
}
296300
}
297301
// Expression.Property(string) is inefficient because it does a case insensitive match

src/AutoMapper/Mappers/CollectionMapper.cs

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -157,6 +157,9 @@ static class ArrayMapper
157157
private static readonly MethodInfo CopyToMethod = typeof(Array).GetMethod("CopyTo", new[] { typeof(Array), typeof(int) });
158158
private static readonly MethodInfo CountMethod = typeof(Enumerable).StaticGenericMethod("Count", parametersCount: 1);
159159
private static readonly MethodInfo MapMultidimensionalMethod = typeof(ArrayMapper).GetStaticMethod(nameof(MapMultidimensional));
160+
private static readonly ParameterExpression Index = Variable(typeof(int), "destinationArrayIndex");
161+
private static readonly BinaryExpression ResetIndex = Assign(Index, Zero);
162+
private static readonly UnaryExpression IncrementIndex = PostIncrementAssign(Index);
160163
private static Array MapMultidimensional(Array source, Type destinationElementType, ResolutionContext context)
161164
{
162165
var sourceElementType = source.GetType().GetElementType();
@@ -199,11 +202,10 @@ public static Expression MapToArray(IGlobalConfiguration configurationProvider,
199202
}
200203
var itemParam = Parameter(sourceElementType, "sourceItem");
201204
var itemExpr = configurationProvider.MapExpression(profileMap, new TypePair(sourceElementType, destinationElementType), itemParam);
202-
var indexParam = Parameter(typeof(int), "destinationArrayIndex");
203-
var setItem = Assign(ArrayAccess(destination, PostIncrementAssign(indexParam)), itemExpr);
204-
return Block(new[] { destination, indexParam },
205+
var setItem = Assign(ArrayAccess(destination, IncrementIndex), itemExpr);
206+
return Block(new[] { destination, Index },
205207
createDestination,
206-
Assign(indexParam, Zero),
208+
ResetIndex,
207209
ForEach(itemParam, sourceExpression, setItem),
208210
destination);
209211
Expression MapFromArray()

0 commit comments

Comments
 (0)