Подтвердить что ты не робот

Почему я должен сделать базовый тип Enum Int32 вместо байта?

Учитывая следующее перечисление:

public enum Operations_PerHourType : byte
{
    Holes = 1,
    Pieces = 2,
    Sheets = 3,
    Strips = 4,
    Studs = 5
}

Когда я запускаю инструмент анализа кода Microsoft, он сообщает мне:

CA1028: Microsoft.Design: если возможно, создайте базовый тип "Enums.Operations_PerHourType" System.Int32 вместо "byte".

У него никогда не будет больше пары возможных значений, поэтому я объявил его байтом. Почему они рекомендуют использовать int32? Дополнительные значения для будущей масштабируемости? Или есть улучшение производительности?

4b9b3361

Ответ 1

Посмотрите MSDN по этой причине.

Вот выдержка:

Перечисление - это тип значения, который определяет набор связанных имен константы. По умолчанию тип данных System.Int32 используется для хранения постоянное значение. Даже если вы можете изменить этот базовый тип, это не рекомендуется или рекомендуется для большинства сценариев. Обратите внимание, что нет значительный прирост производительности достигается за счет использования типа данных, который меньше, чем Int32. Если вы не можете использовать тип данных по умолчанию, вы должен использовать один из интегралов Common Language System (CLS) типы, байты, Int16, Int32 или Int64, чтобы убедиться, что все значения перечисление может быть представлено в CLS-совместимом программировании языки.

Ответ 2

В соответствии с документацией, нет увеличения производительности от использования байта вместо INT32. Если нет причин для этого, они не рекомендуют его менять. Основная идея заключается в том, что .NET оптимизирован для использования INT32 во многих сценариях, и они выбрали это для перечислений по какой-то причине. Вы не получите ничего в своем сценарии, изменив его, так зачем беспокоиться.

http://msdn.microsoft.com/en-us/library/ms182147.aspx

Это также говорит о том, как .NET оптимизирован для использования 32-битных целых чисел: .NET Optimized Int32

Ответ 3

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

Рассмотрим этот пример:

using System;

public enum Operations_PerHourType //   : byte
{
    Holes = 1,
    Pieces = 2,
    Sheets = 3,
    Strips = 4,
    Studs = 5
}

class Program
{
    static void Main()
    {
        long before = GC.GetTotalMemory(false);
        var enums = new Operations_PerHourType[10000];
        long after = GC.GetTotalMemory(false);

        Console.WriteLine(after - before);
        // output  (byte): 12218 (I'm using Mono 2.8)
        // output (Int32): 40960
    }
}

Этот код потребляет примерно 40 Кбайт кучи. Теперь укажите (раскомментируйте) базовый тип как byte и перекомпилируйте. Вау. Вдруг нам понадобится примерно 10 КБ.

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

Однако разработка привычки указывать узкие типы только потому, что это обычно возможно, а иногда и имеет решающее значение, не является хорошей идеей. Экономия памяти редко возникает из-за выравнивания памяти окружающих более широких типов данных. Производительность тогда либо то же, либо немного хуже из-за дополнительных инструкций, необходимых для маскировки пропущенных байтов.

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