【问题标题】:Why does array initialization always resort to int?为什么数组初始化总是求助于int?
【发布时间】:2014-02-28 13:27:02
【问题描述】:

阅读All possible C# array initialization syntaxes 我想知道为什么C# 总是推断int/Int32 的数组,而byteshort 等较小的数据类型就足够了。

new[] { 30, 130, 230 } // sbyte[] suffices but becomes int[]
new[] { -1, 125, -119 } // sbyte[] suffices  but becomes int[]
new[] { -31647, -1337, 23456} // short suffices but becomes int[]

在引用的问题中,Eric Lippert 指出使用了“最佳类型” - 见下文,但 int 是如何成为可能的最佳类型?如果我们要矫枉过正,为什么不使用long呢?

通过计算最佳类型来推断数组元素的类型, 如果有一个,在所有给定的元素中都有类型。一切 元素必须隐式转换为该类型。

我怀疑处理 8 位或 16 位数据类型可能比 32 位结构更快,例如当使用 SIMD 时,四个 byte 实例可以放入一个 int/Int32 的寄存器空间中。我知道SSE instructions are not (widely) used by the JIT Compiler,但是这种使用“int无处不在”确保当 JIT 编译器包含此类优化时它不会有太大帮助。

谁能详细说明这些事实并说明为什么它总是诉诸int

// 编辑 // 我并不真正关心规定没有前缀的文字应该被视为int 的规范。换个说法:

为什么要使用大于所需的数据类型?为什么规范对文字有这个规则? 有什么优点,因为巨大的缺点是远离未来 (SIMD) 优化。

【问题讨论】:

  • 我猜Java在这里不相关。
  • 我认为在 32 位机器中,32 位结构比另一种结构更快。
  • 如果我们想要矫枉过正 =>我们不会,操纵 int32 通常比操纵 int8/int16 快
  • @RohitJain - 感谢您的澄清,我已经编辑了我的帖子以删除对 Java 的引用 - 而不仅仅是关键字:)
  • 有什么缺点?是什么阻止您在声明数组时显式指定类型?老实说,我不明白你的问题。

标签: c# arrays type-conversion array-initialization


【解决方案1】:

为什么要使用大于所需的数据类型?

您以整数进行计算并且可以保证结果适合字节或短字节的业务线应用程序的数量非常少。整数计算结果适合 int 的业务线应用程序的数量巨大

为什么规范对文字有这个规则?

因为这是一个完全明智的规则。它是一致的、清晰的和可以理解的。它在许多语言目标之间做出了很好的折衷,例如合理的性能、与现有非托管代码的互操作性、其他语言用户的熟悉程度以及将数字视为 数字 而不是位模式。绝大多数 C# 程序都使用数字作为数字。

优点是什么,因为巨大的缺点是远离未来 (SIMD) 优化。

我向您保证,千分之一的 C# 程序员不会将“难以利用 SIMD 优化”列为 C# 数组类型推断语义的“巨大缺点”。事实上,你可能是唯一的一个。我当然不会想到。如果您是那种非常关心它的人,那么在数组初始化器中显示类型

C# 的设计目的不是为了从未来可能发明的机器中榨取每一盎司的性能尤其是在类型推断时也不是这样设计的参与了。它旨在提高业务线开发人员的工作效率,而业务线开发人员并不认为columnWidths = new [] { 10, 20, 30 }; 是一个字节数组。

【讨论】:

    【解决方案2】:

    C# 5.0 规范 2.4.4.2

    • 如果文字没有后缀,则它具有可以表示其值的第一种类型:int、uint、long、ulong。

    • 如果文字以 U 或 u 为后缀,则它具有以下类型中的第一个可以表示其值:uint、ulong。

    • 如果文字以 L 或 l 为后缀,则它具有以下类型中的第一个可以表示其值:long、ulong。

    • 如果文字以 UL、Ul、uL、ul、LU、Lu、lU 或 lu 为后缀,则为 ulong 类型。

    您的所有示例都排在该列表的首位...int

    所有整型文字都遵循此规则。这就是为什么var i = 10; 也被推断为int 的原因。

    【讨论】:

    • 感谢您的快速回答,但由于我不是在看文字是如何处理的,所以我澄清了这个问题。
    • 鉴于您的编辑..您的问题是为什么规范对文字有此规则?
    • 是的,完全正确。看来我很难找到正确的问题。
    • 有更多洞察力的人必须回答这个问题。但是,我有一种感觉,因为 CLR 中的算术运算实际上并没有在小于 32 位 int 的任何东西上执行。任何小于该值的内容都会被提升,以便操作位于平台的字长边界上。通过将 32 位推断为默认值……您可以避免(毫无疑问……相当小的)促销成本。
    【解决方案3】:

    当你把整数值没有任何后缀30, 130, 230你声明int32值;所以

    new[] { 30, 130, 230 }; // <- array of int's
    

    如果你想要字节数组,你必须把它明确

      new byte[] { 30, 130, 230 }; // <- treat each value as byte
    

    【讨论】:

      【解决方案4】:

      您作为示例使用的文字都有System.Int32,而这些值可以在不丢失的情况下存储为窄整数类型(例如System.Int16),语法为System.Int32

      由于每个数组的所有指定成员都是System.Int32,因此数组的类型为System.Int32[]

      当然,可以定义一种语言,其中整数文字(没有其他指示,如后缀)具有“足以容纳该值的最小整数类型”类型,该语言不是 C#。

      在最新的 - V5.0 - C# 语言规范(来自我的 VS2013 安装)中,在第 2.4.4.2 节中:

      整数字面量用于写入intuintlongulong 类型的值。

      即。如果没有演员表,就无法编写 bytesbyteshortunsigned short 文字。

      【讨论】:

      • 和@Simon一样,规范是一回事,但为什么没有像你精细描述“足以容纳该值的最小整数类型”那样制定语言?
      • @M.Mimpen 因为这是设计师的决定。你需要问他们,除非他们在某个地方写了一个理由(但我认为他们没有)。
      【解决方案5】:

      我相信在本机位大小下运行总是会更快,所以 int 用于 32 位机器,因此约定。

      这也意味着对于运行 64 位应用程序,int64 比 int 更适合用于数组。

      【讨论】:

      • 听起来很合理,但你有任何证据证明int64 用于int32 机器上的int32 操作吗?
      • 啊,不,我的意思是如果你明确地将你的数字声明为 int64 对你的程序会更好——在 C# 中,int 总是意味着 int32
      • Sriram - 我认为当时机器的标准位数可能与为什么 c# 的设计者最初选择 int32 作为他们的“默认”int 位数有关。
      猜你喜欢
      • 1970-01-01
      • 2012-11-10
      • 1970-01-01
      • 2013-09-07
      • 2020-05-30
      • 1970-01-01
      • 2011-10-29
      • 2014-11-07
      • 2015-11-12
      相关资源
      最近更新 更多