DistIL icon indicating copy to clipboard operation
DistIL copied to clipboard

Copy elision for arrays and lists

Open dubiousconst282 opened this issue 2 years ago • 1 comments

Lists are often used as an array builder helper, but it isn't as ideal because it always requires a copy. If the list can be pre-resized to a fixed size, the copy can be removed entirely by taking out the inner array at the end:

// Source
int[] values = [..Enumerable.Range(0, 100)];


// Compiled IL
var list = new List<int>();
foreach (int x in Enumerator.Range(0, 100)) {
    list.Add(x);
}
var array = list.ToArray(); // also last use of list (non-escaping)


// Optimized (checks are obviously redundant if known statically, but that could be hard to determine.)
var array = list._array._length == _list._size ? _list._array : _list.ToArray()

Defensive copies are also a relatively common case of this and it should be easier to determine the length for them.

This might be more easily implemented as an extension to #31 and/or the builder pattern in #26.

dubiousconst282 avatar Dec 02 '23 20:12 dubiousconst282

Some collection literal patterns will see further optimizations in 8.0.1xx or 8.0.200 in the form of "performance bufixes". I did not know it was a thing but apparently it is.

Noting this here as it will be worth to re-examine what they are lowered to after the fact.

neon-sunset avatar Dec 02 '23 20:12 neon-sunset