NET Integer vs Int 16应该是用哪一个?

内容来源于 Stack Overflow,并遵循CC BY-SA 3.0许可协议进行翻译与使用

  • 回答 (2)
  • 关注 (0)
  • 查看 (23)

我有一个可疑的编码习惯。

当我需要通过它的数量限制是根据项目的小单子迭代32000,我用Int16我的的变量类型,而不是Integer。我这样做是因为我认为使用Int16效率比完整效率更高Integer

我错了吗?使用Int16vs和an 之间没有有效的性能差异Integer吗?我应该停止使用Int16,只是坚持Integer我所有的计数/迭代需求?

提问于
用户回答回答于

根据以下参考资料,运行时优化了Int32的性能,并将其推荐用于计数器和其他经常访问的操作。

从这本书:MCTS Self-Paced Training Kit(考试70-536):Microsoft®.NET Framework 2.0-应用程序开发基础

第1章:“框架基础” 第1课:“使用价值类型”

最佳实践:使用内置类型优化性能 运行时优化32位整数类型(Int32和UInt32)的性能,因此将这些类型用于计数器和其他频繁访问的整型变量。 对于浮点操作,Double是最有效的类型,因为这些操作是通过硬件优化的。

此外,同一部分的表1-1列出了每种类型的建议用途。与此讨论有关:

  • Int16 - 互操作和其他专门用途
  • Int32 - 整数和计数器
  • Int64 - 大整数
用户回答回答于

当通过索引循环访问数组或集合时,应该几乎总是使用Int32Int64(并且,不,没有通过使用UInt32或获得功劳UInt64)。

效率较低的最明显原因是BCL中的所有数组和集合索引都Int32带有s,所以隐式转换总是会在试图使用Int16s作为索引的代码中发生。

的不太明显原因(以及阵列采取的原因Int32作为指标)是,CIL说明书说,所有的操作栈的值是任一 Int32Int64。每次任一负荷或值存储到任何其他整数型(ByteSByteUInt16Int16UInt32,或UInt64),有涉及的隐式转换的操作。无符号类型没有加载的惩罚,但为了存储该值,这相当于截断和可能的溢出检查。对于签名类型,每个加载签名都会扩展,并且每个商店签名都会崩溃(并且可能会有溢出检查)。

最会伤害你的地方是循环本身,而不是数组访问。例如,采取这个看起来无辜的循环:

for (short i = 0; i < 32000; i++) {
    ...
}

看起来不错,对吧?不!基本上可以忽略初始化(short i = 0),因为它只发生一次,但比较(i<32000)和递增(i++)部分发生32000次。下面是一些关于在机器级别看起来像什么的代码:

  Int16 i = 0;
LOOP:
  Int32 temp0 = Convert_I16_To_I32(i); // !!!
  if (temp0 >= 32000) goto END;
  ...
  Int32 temp1 = Convert_I16_To_I32(i); // !!!
  Int32 temp2 = temp1 + 1;
  i = Convert_I32_To_I16(temp2); // !!!
  goto LOOP;
END:

在那里有3次转换运行32000次。他们可以完全避免只使用一个Int32Int64

正如我在评论中所说的,我现在已经写了一篇关于这个主题的博客文章,.NET Integral Data Types And You

扫码关注云+社区