Пустой массив в.NET используют какое-либо пространство?

24
задан Orion Edwards 30 September 2008 в 20:32
поделиться

7 ответов

Даже если бы это называют "сотнями и сотнями" времен, я сказал бы, что это - преждевременная оптимизация. Если результат более ясен как пустой массив, используйте это.

Теперь для фактического ответа: да, пустой массив берет некоторую память. Это имеет обычный объект наверху (8 байтов на x86, я верю), и 4 байта для количества. Я не знаю, существует ли что-нибудь кроме того, но это не совсем свободно. (Это невероятно дешево хотя...)

, К счастью, существует оптимизация, которую можно сделать, не ставя под угрозу сам API: имейте "константу" пустого массива. Я сделал другое небольшое изменение для создания кода более ясным, если Вы разрешите...

private static readonly string[] EmptyStringArray = new string[0];

string[] GetTheStuff() {
    if( somePredicate() ) {
        List<string> s = new List<string>(); 
        // imagine we load some data or something
        return s.ToArray();
    } else {
        return EmptyStringArray;
    }
}

при нахождении этого часто Вы могли бы даже создать универсальный класс со статическим участником для возврата пустого массива правильного типа. Путем работа дженериков.NET делает это тривиальным:

public static class Arrays<T> {
    public static readonly Empty = new T[0];
}

(Вы могли обернуть его в свойство, конечно.)

Тогда просто использование: Arrays< строка>.Empty;

РЕДАКТИРОВАНИЕ: я только что помнил сообщение Eric Lippert на массивах . Вы уверены, что массив самый соответствующий тип должен возвратиться?

56
ответ дан Jon Skeet 16 October 2019 в 07:43
поделиться

Заявленные массивы должны будут всегда содержать следующую информацию:

  • Разряд (количество размеров)
  • Тип, который будет содержаться
  • Длина каждого размера

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

Что касается типов возврата, я соглашаюсь, что пустой массив должен быть возвращен вместо пустого указателя.

[еще 118] информация здесь: Типы массива в.NET

5
ответ дан Jon Limjap 16 October 2019 в 07:43
поделиться

Да, как другие сказали, пустой массив поднимает несколько байтов для объектного заголовка и поля длины.

, Но если Вы волнуетесь по поводу производительности, что фокусируетесь на неправильном ответвлении выполнения в этом методе. Я был бы намного более обеспокоен запрос ToArray к заполненному списку, который приведет к выделению памяти, равному его внутреннему размеру и копии памяти содержания списка в него.

, Если Вы действительно хотите улучшить производительность тогда (если возможный) возвращают список непосредственно, заставляя возврат ввести один из: List<T>, IList<T>, ICollection<T>, IEnumerable<T> в зависимости от того, в каких средствах Вы нуждаетесь от него (отмечают, что менее конкретный лучше в общем случае).

4
ответ дан Greg Beech 16 October 2019 в 07:43
поделиться

Я предположил бы, что пустой массив использует только пространство, должен был выделить сам объектный указатель.

Из памяти в инструкциях по API говорится, что необходимо всегда возвращать пустой массив из метода, который возвращает массив вместо того, чтобы возвратить пустой указатель, таким образом, я оставил бы код путем, это невнимательно. Тем путем вызывающая сторона знает, что он, как гарантируют, получит массив (даже пустой) и не должен проверять на пустой указатель с каждым вызовом.

Редактирование: ссылка о возврате пустых массивов:

http://wesnerm.blogs.com/net_undocumented/2004/02/empty_arrays.html

3
ответ дан Matt Hamilton 16 October 2019 в 07:43
поделиться

Другие ответили на Ваш вопрос приятно. Таким образом, просто простая точка для создания...

я постарался бы не возвращать массив (если Вы не можете). Палка с IEnumerable и затем можно использовать Enumerable.Empty<T>() от API LINQ. Очевидно, Microsoft оптимизировала этот сценарий для Вас.

IEnumerable<string> GetTheStuff()
{
    List<string> s = null;
    if (somePredicate())
    {
        var stuff = new List<string>();
        // load data
        return stuff;
    }

    return Enumerable.Empty<string>();
}
3
ответ дан Drew Noakes 16 October 2019 в 07:43
поделиться

Это не прямой ответ на Ваш вопрос.

Read, почему массивы считают несколько вредными . Я предложил бы, чтобы Вы возвратили IList< string> в этом случае и реструктурируйте код немного:

IList<string> GetTheStuff() {
    List<string> s = new List<string>();
    if( somePredicate() ) {
        // imagine we load some data or something
    }
    return s;
}

Таким образом вызывающая сторона не должна заботиться о пустых возвращаемых значениях.

<час>

РЕДАКТИРОВАНИЕ : Если возвращенный список не должен быть доступным для редактирования, можно обернуть Список в ReadOnlyCollection. Просто измените последнюю строку на. Я также рассмотрел бы эту лучшую практику.

    return new ReadOnlyCollection(s);
2
ответ дан VVS 16 October 2019 в 07:43
поделиться

Если я пойму правильно, небольшое количество памяти будет выделено для массивов строк. Вы кодируете, по существу требует, чтобы универсальный список был создан так или иначе, итак, почему не просто возвращают это?

[РЕДАКТИРОВАНИЕ] Удалил версию кода, который возвратил нулевое значение. Другие ответы, отговаривающие от пустых возвращаемых значений при этом обстоятельстве, кажется, лучший совет [/РЕДАКТИРОВАНИЕ]

List<string> GetTheStuff()
{
   List<string> s = new List<string();
   if (somePredicarte())
   {
      // more code
   }
   return s;
}
0
ответ дан Dr8k 16 October 2019 в 07:43
поделиться
Другие вопросы по тегам:

Похожие вопросы: