Возможны ли эффективные массивы фиксированного размера без использования небезопасного кода в .NET? - PullRequest
9 голосов
/ 03 ноября 2010

Есть ли хороший способ реализации массива фиксированного размера в .NET, который не требует небезопасного кода?

Моя цель - создать тип значения, который представляет фиксированныйразмер массива, который может быть встроен (включен в качестве члена) в другие типы - т.е. я специально надеюсь избежать создания массива как отдельного объекта для типа, который его объявляет.

Я понимаю, что реализация .NETмассивов превосходен и поддерживается на уровне CLR / CIL - и на самом деле не хочу спорить, использовать ли массивы или нет ... исследование здесь заключается в том, возможна ли безопасная реализация с фиксированным размером значения типас почти такой же хорошей эффективностью.

Ответы [ 2 ]

5 голосов
/ 03 ноября 2010

Цель состоит в том, чтобы иметь возможность иметь массив типа значения фиксированного размера, который можно использовать в качестве частного члена для других типов.Рассмотрим пользовательский словарь или реализацию связанного списка ... число выделений кучи может быть уменьшено, если каждый контейнер / узел выровнен, чтобы содержать собственный массив фиксированного размера.1006 * Создание массива типом значения не обязательно означает, что он будет храниться в стеке.Фактически, если это тип значения, встроенный в ссылочный тип, он, скорее всего, будет храниться в куче с ссылочным типом, а не в стеке.

Таким образом, присвоение этому типу значения никоим образом не уменьшит выделения кучи.

Дополнительная информация здесь: http://blogs.msdn.com/b/ericlippert/archive/2010/09/30/the-truth-about-value-types.aspx

2 голосов
/ 03 ноября 2010

После некоторых исследований с использованием рефлектора выясняется, что следующее представляет приемлемое (с точки зрения производительности) решение, поскольку C # компилирует оператор switch для целых чисел в оператор CIL switch, который реализован как jump-list ...то есть - геттер выполняет около 11 CIL-инструкций, что прекрасно.

 public struct EmbeddedArray<T>
    {
        private T _element0;
        private T _element1;
        private T _element2;

        public int Length { get { return 3; } }


        public T this[int index]
        {
            get
            {
                switch (index)
                {
                    case 0:
                        return _element0;
                    case 1:
                        return _element1;
                    case 2:
                        return _element2;
                }
                throw new ArgumentOutOfRangeException("index");

            }
        }
    }

Пожалуйста, смотрите комментарий Ганса ниже.Оказывается, что это не как производительность, как я надеялся ... как только CIL скомпилирован в машинный код, измеренная производительность будет далека от того, что даст массив .NET.

...