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

Kev*_*vin 53 .net c# enums

鉴于以下枚举:

public enum Operations_PerHourType : byte
{
    Holes = 1,
    Pieces = 2,
    Sheets = 3,
    Strips = 4,
    Studs = 5
}
Run Code Online (Sandbox Code Playgroud)

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

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

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

Jas*_*own 40

看看MSDN的原因.

这是一段摘录:

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


Jir*_*ika 24

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

考虑这个样本:

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
    }
}
Run Code Online (Sandbox Code Playgroud)

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

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

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

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


kem*_*002 21

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

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

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

  • 它不是针对使用INT32优化的.NET,而是底层CPU,最显着的原因是汇编指令操作数的寄存器大小/大小 - 在32位系统上恰好是32位.如果值的大小不同,则需要对齐/填充,并且需要额外的cpu周期.有趣的是,你在链接的主题中提到了这一点.最有可能的是,开销很小.关键在于,出于性能原因使用BYTE而不是INT32实际上会产生相反的效果.这就是每种HL语言的情况. (2认同)