.NET Integer vs Int16?

Mat*_*ino 50 .net c# vb.net variables types

我有一个可疑的编码实践.

当我需要遍历计数限制不足的项目的小列表时32000,我使用的Int16是我的i变量类型而不是Integer.我这样做是因为我认为使用它Int16比完全吹制效率更高Integer.

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

Ale*_*man 84

当按索引循环遍历数组或集合时,您几乎应该始终使用Int32Int64(并且,不,您不会通过使用UInt32或获得信用UInt64).

效率较低的最明显的原因是在BCL中找到的所有数组和集合索引都采用Int32s,因此在尝试使用s作为索引的代码中总是会发生隐式转换Int16.

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

这对你最有害的地方是循环本身,而不是数组访问.例如,看看这个看似无辜的循环:

for (short i = 0; i < 32000; i++) {
    ...
}
Run Code Online (Sandbox Code Playgroud)

看起来不错吧?不!您基本上可以忽略initial(short i = 0),因为它只发生一次,但compare(i<32000)和incrementing(i++)部分发生了32000次.这里有一些pesudo代码,用于处理机器级别的内容:

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

其中有3次转换,运行32000次.而且只要使用Int32或者它们就可以完全避免它们Int64.

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

  • 优秀的解释.羞耻你没被接受! (8认同)
  • 谢谢,亚丁.我已经将这个添加到我的队列中,以便我在实际创建博客时应该发布博客.我见过人们过去经常犯这个错误. (3认同)

小智 52

根据以下参考,运行时优化Int32的性能,并为计数器和其他频繁访问的操作推荐它们.

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

第1章:"框架基础"
第1课:"使用值类型"

最佳实践:使用内置类型优化性能

运行时优化了32位整数类型(Int32和UInt32)的性能,因此将这些类型用于计数器和其他经常访问的整数变量.

对于浮点运算,Double是最有效的类型,因为这些操作是由硬件优化的.

此外,同一节中的表1-1列出了每种类型的推荐用途.与此讨论相关:

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


Cur*_*her 11

Int16实际上可能效率较低,因为用于字访问的x86指令比用于双字访问的指令占用更多空间.这取决于JIT的作用.但无论如何,当在迭代中用作变量时,几乎肯定不会有效.


Nil*_*nck 9

反之亦然.

32(或64)位整数比int16快.通常,本机数据类型是最快的.

如果你想让你的数据结构尽可能精简,那么Int16很不错.这节省了空间并可以提高性能.