Skip to content

Commit

Permalink
Merge pull request #2731 from ElektroKill/transform-initializer-reduc…
Browse files Browse the repository at this point in the history
…e-alloc

Reduce allocations in TransformArrayInitializers
  • Loading branch information
dgrunwald authored Jul 12, 2022
2 parents fecb5a3 + 760a6a6 commit 06039f2
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 2 deletions.
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright (c) 2015 Siegfried Pammer
// Copyright (c) 2015 Siegfried Pammer
//
// Permission is hereby granted, free of charge, to any person obtaining a copy of this
// software and associated documentation files (the "Software"), to deal in the Software
Expand Down Expand Up @@ -620,16 +620,21 @@ static Block BlockFromInitializer(ILVariable v, IType elementType, int[] arrayLe
var block = new Block(BlockKind.ArrayInitializer);
block.Instructions.Add(new StLoc(v, new NewArr(elementType, arrayLength.Select(l => new LdcI4(l)).ToArray())));
int step = arrayLength.Length + 1;

var indices = new List<ILInstruction>();
for (int i = 0; i < values.Length / step; i++)
{
// values array is filled backwards
var value = values[step * i];
var indices = new List<ILInstruction>();

indices.EnsureCapacity(step - 1);
for (int j = step - 1; j >= 1; j--)
{
indices.Add(values[step * i + j]);
}

block.Instructions.Add(StElem(new LdLoc(v), indices.ToArray(), value, elementType));
indices.Clear();
}
block.FinalInstruction = new LdLoc(v);
return block;
Expand Down Expand Up @@ -774,6 +779,8 @@ static bool DecodeArrayInitializer(BlobReader initialValue, int[] arrayLength,
if (initialValue.RemainingBytes < (totalLength * elementSize))
return false;

output.EnsureCapacity(totalLength + totalLength * arrayLength.Length);

for (int i = 0; i < totalLength; i++)
{
output.Add(decoder(ref initialValue));
Expand Down
25 changes: 25 additions & 0 deletions ICSharpCode.Decompiler/Util/CollectionExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -371,6 +371,31 @@ public static void RemoveLast<T>(this IList<T> list)
return first;
}

#if !NETCORE
public static int EnsureCapacity<T>(this List<T> list, int capacity)
{
if (capacity < 0)
throw new ArgumentOutOfRangeException(nameof(capacity));
if (list.Capacity < capacity)
{
const int DefaultCapacity = 4;
const int MaxLength = 0X7FFFFFC7;

int newcapacity = list.Capacity == 0 ? DefaultCapacity : 2 * list.Capacity;

if ((uint)newcapacity > MaxLength)
newcapacity = MaxLength;

if (newcapacity < capacity)
newcapacity = capacity;

list.Capacity = newcapacity;
}

return list.Capacity;
}
#endif

#region Aliases/shortcuts for Enumerable extension methods
public static bool Any<T>(this ICollection<T> list) => list.Count > 0;
public static bool Any<T>(this T[] array, Predicate<T> match) => Array.Exists(array, match);
Expand Down

0 comments on commit 06039f2

Please sign in to comment.