.NET整数与Int16?
我有一个可疑的编码习惯。
当我需要迭代计数限制在32000
的项目的小列表时,我使用Int16
而不是Integer
我的variablestypes。 我这样做是因为我认为使用Int16
比整个Integer
更有效率。
我错了吗? 使用Int16
与Integer
之间没有有效的性能差异吗? 我应该停止使用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 – 大整数
当通过索引循环访问数组或集合时, 几乎总是使用Int32
或Int64
(并且,不,您不能通过使用UInt32
或UInt64
获得功劳)。
效率不高的最明显原因是在BCL中find的所有数组和集合索引都采用Int32
,所以在尝试使用Int16
s作为索引的代码中总是会发生隐式转换。
不太明显的原因(以及数组将Int32
作为索引的原因)是CIL规范说所有的操作堆栈值都是Int32
或Int64
。 每次您将值加载或存储到任何其他整数types( Byte
, SByte
, UInt16
, Int16
, UInt32
或UInt64
)时,都会有一个隐式转换操作。 无符号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次。 而且只要使用Int32
或Int64
就可以完全避免。
更新:正如我在评论中所说的,现在我已经写了一篇关于这个主题的博客文章, .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快,因为内存分配