Как избежать избыточной временной копии при использовании элемента разворота коллекции?C#

Место общения программистов C#
Ответить
Anonymous
 Как избежать избыточной временной копии при использовании элемента разворота коллекции?

Сообщение Anonymous »

Я пишу неизменную коллекцию типа, обернув массив. Я хотел бы, чтобы оператор спреда сбора работал как можно более эффективно с моим типом коллекции. < /P>
MyCollection coll = new MyCollection([1, 2, 3]);
MyCollection myColl = [.. coll];

Учитывая реализацию ниже (минимальная Repro), вторая строка здесь сначала вызовет перечисление. Затем мой конструктор должен снова распределить и копировать, так как нет основного массива или что -то в этом роде, что я мог бы использовать непосредственно там, даже если я хотел. Компилятор действительно хочет, чтобы вы предоставили метод, который принимает в Readonlyspan и ничего больше. Я попытался добавить перегрузку массива, и она не выберет ее. Что касается реализации различных интерфейсов, то iCollection означает, что, по крайней мере, копирование будет вызвана, и я могу контролировать, как это работает, но это не избегает копии.
Оба ImmutableearRay и List , кажется, имеют жесткие оптимизации. Компилятор c вызывает ImmutableCollectionsmarshal.asimutableArray и перечисляющую. (Примечание: sharplab.io дает различную (худшую) генерацию кода из того, что я вижу в последнем vs). < /P>
using System;
using System.Collections;
using System.Collections.Generic;
using System.Runtime.CompilerServices;

[CollectionBuilder(typeof(MyCollection), nameof(Create))]
public class MyCollection : ICollection
{
public static MyCollection Create(ReadOnlySpan values) =>
new(values);

int[] _values;

public int Count => _values.Length;

public MyCollection(ReadOnlySpan values) =>
_values = values.ToArray();

public IEnumerator GetEnumerator() => throw new NotImplementedException();
IEnumerator IEnumerable.GetEnumerator() => throw new NotImplementedException();
public bool IsReadOnly => throw new NotImplementedException();
public void Add(int item) => throw new NotImplementedException();
public void Clear() => throw new NotImplementedException();
public bool Contains(int item) => throw new NotImplementedException();
public void CopyTo(int[] array, int arrayIndex) => throw new NotImplementedException();
public bool Remove(int item) => throw new NotImplementedException();
}


Подробнее здесь: https://stackoverflow.com/questions/797 ... ad-element
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «C#»