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


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

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

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

CA1028: Microsoft.Дизайн : Если возможно, сделайте базовый тип перечисления.Operations_PerHourType ' System.Int32 вместо 'byte'.

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

3 52

3 ответа:

посмотреть MSDN по той же причине.

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

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

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

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

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 толпа, для которой оптимизирована среда выполнения, пока вам не придется начать профилирование и адресацию реальных свиней памяти в вашем приложении.

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

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

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