为什么我应该使用Enum Int32的底层类型而不是字节?

时间:2022-07-22 16:06:25

Given the following enum:

鉴于以下枚举:

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

When I run the Microsoft code analysis tool, it tells me:

当我运行Microsoft代码分析工具时,它告诉我:

CA1028 : Microsoft.Design : If possible, make the underlying type of 'Enums.Operations_PerHourType' System.Int32 instead of 'byte'.

CA1028:Microsoft.Design:如果可能,请创建基础类型“Enums.Operations_PerHourType”System.Int32而不是“byte”。

It will never have more than a couple possible values, so I declared it as a byte. Why would they recommend using int32? More values for future scalability? Or is there a performance improvement?

它永远不会超过几个可能的值,所以我将其声明为一个字节。他们为什么建议使用int32?未来可扩展性的更多价值?或者是否有性能提升?

3 个解决方案

#1


40  

Have a look on MSDN for the reason.

看看MSDN的原因。

Here is an excerpt:

这是一段摘录:

An enumeration is a value type that defines a set of related named constants. By default, the System.Int32 data type is used to store the constant value. Even though you can change this underlying type, it is not necessary or recommended for most scenarios. Note that no significant performance gain is achieved by using a data type that is smaller than Int32. If you cannot use the default data type, you should use one of the Common Language System (CLS)-compliant integral types, Byte, Int16, Int32, or Int64 to make sure that all values of the enumeration can be represented in CLS-compliant programming languages.

枚举是一种值类型,它定义一组相关的命名常量。默认情况下,System.Int32数据类型用于存储常量值。即使您可以更改此基础类型,但对于大多数方案而言,它不是必需的或推荐的。请注意,使用小于Int32的数据类型不会获得显着的性能提升。如果您不能使用默认数据类型,则应使用符合公共语言系统(CLS)的整数类型之一,Byte,Int16,Int32或Int64,以确保枚举的所有值都可以在符合CLS的条件下表示编程语言。

#2


22  

There are specific situations where narrowing the underlying type brings some advantages, for example performance related or forcing a particular memory layout when interfacing to unmanaged code.

在某些特定情况下,缩小底层类型会带来一些优势,例如与非托管代码接口时性能相关或强制特定内存布局。

Consider this sample:

考虑这个样本:

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
    }
}

This code consumes roughly 40 KB of the heap. Now specify (uncomment) the underlying type as byte and recompile. Wow. Suddenly we only need roughly 10 KB.

此代码占用大约40 KB的堆。现在将基础类型指定(取消注释)为byte并重新编译。哇。突然间我们只需要大约10 KB。

Compacting memory like this may sometimes make a program slower, not faster, depending on particular access patterns and data sizes. There is no way to know for sure than to make some measurements and attempt to generalize to other possible circumstances. Sequential traversal of smaller data is usually faster.

像这样压缩存储器有时可能使程序变慢,而不是更快,这取决于特定的访问模式和数据大小。没有办法确定而不是进行一些测量并尝试推广到其他可能的情况。较小数据的顺序遍历通常更快。

However, developing a habit of specifying narrow types just because it is usually possible and sometimes crucial, is not a good idea. Memory savings rarely materialize due to memory alignment of surrounding wider data types. Performance is then either the same or slightly worse due to additional instructions needed to mask away padding bytes.

然而,养成一种习惯,只是因为它通常是可能的,有时是至关重要的,指定窄类型,这不是一个好主意。由于周围更广泛的数据类型的内存对齐,内存节省很少实现。由于屏蔽填充字节所需的附加指令,性能要么相同要么稍差。

As another answer has already put it well, follow the Int32 crowd that the runtime is optimized for, until you have to start profiling and addressing real memory hogs in your application.

正如另一个答案已经说得好,请遵循运行时优化的Int32人群,直到您必须开始分析和解决应用程序中的实际内存占用。

#3


21  

According to the documentation, there is no performance gain from using a byte instead of INT32. Unless there is a reason to do so, they recommend not changing it. The underlying idea, is that .NET is optimized for using INT32 in many scenarios, and they selected that for enums for a reason. You don't get anything in your scenario by changing it, so why bother.

根据文档,使用字节而不是INT32没有性能提升。除非有理由这样做,否则他们建议不要更改它。根本的想法是,.NET在许多情况下都针对使用INT32进行了优化,并且出于某种原因他们选择了枚举。通过更改它,您的方案中没有任何内容,所以为什么要这么麻烦。

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

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

This also talks about how .NET is optimized to use 32 bit integers: .NET Optimized Int32

这也讨论了如何优化.NET以使用32位整数:.NET Optimized Int32

#1


40  

Have a look on MSDN for the reason.

看看MSDN的原因。

Here is an excerpt:

这是一段摘录:

An enumeration is a value type that defines a set of related named constants. By default, the System.Int32 data type is used to store the constant value. Even though you can change this underlying type, it is not necessary or recommended for most scenarios. Note that no significant performance gain is achieved by using a data type that is smaller than Int32. If you cannot use the default data type, you should use one of the Common Language System (CLS)-compliant integral types, Byte, Int16, Int32, or Int64 to make sure that all values of the enumeration can be represented in CLS-compliant programming languages.

枚举是一种值类型,它定义一组相关的命名常量。默认情况下,System.Int32数据类型用于存储常量值。即使您可以更改此基础类型,但对于大多数方案而言,它不是必需的或推荐的。请注意,使用小于Int32的数据类型不会获得显着的性能提升。如果您不能使用默认数据类型,则应使用符合公共语言系统(CLS)的整数类型之一,Byte,Int16,Int32或Int64,以确保枚举的所有值都可以在符合CLS的条件下表示编程语言。

#2


22  

There are specific situations where narrowing the underlying type brings some advantages, for example performance related or forcing a particular memory layout when interfacing to unmanaged code.

在某些特定情况下,缩小底层类型会带来一些优势,例如与非托管代码接口时性能相关或强制特定内存布局。

Consider this sample:

考虑这个样本:

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
    }
}

This code consumes roughly 40 KB of the heap. Now specify (uncomment) the underlying type as byte and recompile. Wow. Suddenly we only need roughly 10 KB.

此代码占用大约40 KB的堆。现在将基础类型指定(取消注释)为byte并重新编译。哇。突然间我们只需要大约10 KB。

Compacting memory like this may sometimes make a program slower, not faster, depending on particular access patterns and data sizes. There is no way to know for sure than to make some measurements and attempt to generalize to other possible circumstances. Sequential traversal of smaller data is usually faster.

像这样压缩存储器有时可能使程序变慢,而不是更快,这取决于特定的访问模式和数据大小。没有办法确定而不是进行一些测量并尝试推广到其他可能的情况。较小数据的顺序遍历通常更快。

However, developing a habit of specifying narrow types just because it is usually possible and sometimes crucial, is not a good idea. Memory savings rarely materialize due to memory alignment of surrounding wider data types. Performance is then either the same or slightly worse due to additional instructions needed to mask away padding bytes.

然而,养成一种习惯,只是因为它通常是可能的,有时是至关重要的,指定窄类型,这不是一个好主意。由于周围更广泛的数据类型的内存对齐,内存节省很少实现。由于屏蔽填充字节所需的附加指令,性能要么相同要么稍差。

As another answer has already put it well, follow the Int32 crowd that the runtime is optimized for, until you have to start profiling and addressing real memory hogs in your application.

正如另一个答案已经说得好,请遵循运行时优化的Int32人群,直到您必须开始分析和解决应用程序中的实际内存占用。

#3


21  

According to the documentation, there is no performance gain from using a byte instead of INT32. Unless there is a reason to do so, they recommend not changing it. The underlying idea, is that .NET is optimized for using INT32 in many scenarios, and they selected that for enums for a reason. You don't get anything in your scenario by changing it, so why bother.

根据文档,使用字节而不是INT32没有性能提升。除非有理由这样做,否则他们建议不要更改它。根本的想法是,.NET在许多情况下都针对使用INT32进行了优化,并且出于某种原因他们选择了枚举。通过更改它,您的方案中没有任何内容,所以为什么要这么麻烦。

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

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

This also talks about how .NET is optimized to use 32 bit integers: .NET Optimized Int32

这也讨论了如何优化.NET以使用32位整数:.NET Optimized Int32