.NET整数与Int16?

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

当我需要迭代计数限制在32000的项目的小列表时,我使用Int16而不是Integer 我的variablestypes。 我这样做是因为我认为使用Int16比整个Integer更有效率。

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

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

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

第1章:“框架基础”
第1课:“使用值types”

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

运行时优化了32位整数types(Int32和UInt32)的性能,因此将这些types用于计数器和其他频繁访问的整型variables。

对于浮点操作,Double是最有效的types,因为这些操作是由硬件优化的。

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

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

当通过索引循环访问数组或集合时, 几乎总是使用Int32Int64 (并且,不,您不能通过使用UInt32UInt64获得功劳)。

效率不高的最明显原因是在BCL中find的所有数组和集合索引都采用Int32 ,所以在尝试使用Int16 s作为索引的代码中总是会发生隐式转换。

不太明显的原因(以及数组将Int32作为索引的原因)是CIL规范说所有的操作堆栈值都是Int32Int64 。 每次您将值加载或存储到任何其他整数types( ByteSByteUInt16Int16UInt32UInt64 )时,都会有一个隐式转换操作。 无符号types没有加载的惩罚,但为了存储值,这相当于一个截断和一个可能的溢出检查。 对于签名types, 每个加载签名扩展,每个商店签名崩溃(并有一个可能的溢出检查)。

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

 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

Int16可能实际上效率较低,因为用于字访问的x86指令占用比用于双字访问的指令更多的空间。 这将取决于JIT的作用。 但是无论如何,在迭代中作为variables使用它几乎肯定不会高效。

事实恰恰相反。

32(或64)位整数比int16快。 一般来说,本机数据types是最快的。

如果你想让你的数据结构尽可能精简,那么Int16是很好的。 这样可以节省空间并可以提高性能。

在现代硬件上,任何性能差异都将如此微小,以至于所有的意图和目的都没有什么区别。 尝试编写几个testing工具,并运行它们几百次,平均循环完成时间,你会明白我的意思。

从存储的angular度来看,如果资源非常有限 – embedded式系统有很小的堆栈,为慢速networking(例如GPRS等)devise的有线协议等等,这可能是有意义的。

永远不要效率。

从编译器到编译器和平台到平台,什么是或不是更高效。 除非你真的testing过,否则无法判断int16或int是否更有效。

除非遇到使用int16修补程序的性能问题,否则我会坚持使用整数。

在32位机器上使用Int32(或在64位机器上使用Int64)以获得最快的性能。 如果你真的担心它占用的空间,可以使用较小的整数types(虽然可能会更慢)。

这里的其他地方是正确的,如果你需要它用于极端的存储需求,或者在业务对象领域的另一个级别上执行,你只需要less于 Int32(对于32位代码)/ Int64(对于64位代码)在这种情况下,当然还是有一定程度的validation)。

一般来说,在出现性能问题之前不要担心效率问题。 在这种情况下,分析它。 如果猜测和检查两种方式,而分析没有足够的帮助,检查IL代码。

好问题,但。 你正在学习更多关于编译器如何做的事情。 如果你想学习更高效的编程,学习IL的基础知识以及C#/ VB编译器如何完成他们的工作将是一个好主意。

我无法想象Int16与int有什么显着的性能提升。

您可以在variables声明中保存一些位。

当规格发生变化以及你正在计算的任何东西都可以在32767以上,并且你发现当你的应用程序开始抛出exception的时候,这绝对不值得一提。

使用小于Int32的数据types没有显着的性能增益,事实上,我读了一些地方,使用Int32会比Int16快,因为内存分配