.NET Integer与Int16?
我有一个可疑的编码实践。
当我需要遍历一小部分计数限制在32000以下的项目时,我将Int16用作我的i变量类型而不是Integer。之所以这样做,是因为我认为使用Int16比完整的Integer更有效。
我错了吗?使用Int16和Integer之间没有有效的性能差异吗?我应该停止使用Int16还是只使用Integer来满足我的所有计数/迭代需求?
解决方案
反之亦然。
32(或者64)位整数比int16快。通常,本机数据类型是最快的一种。
如果要使数据结构尽可能精简,Int16很好。这样可以节省空间并可以提高性能。
Int16实际上可能效率较低,因为用于字访问的x86指令要比用于双字访问的指令占用更多的空间。这将取决于JIT的功能。但是无论如何,在迭代中用作变量时,几乎可以肯定效率不高。
永远不要以为效率。
效率高低与效率低下取决于编译器和平台之间的差异。除非我们进行了实际测试,否则无法判断int16或者int效率更高。
除非我们遇到使用int16修复的可靠性能问题,否则我只会坚持使用int。
我无法想象Int16与int会有任何显着的性能提升。
我们将一些位保存在变量声明中。
当规格更改时,绝对不值得麻烦,现在我们所计数的值都可以超过32767,并且我们发现当应用程序开始引发异常时...
在现代硬件上,任何性能差异都将非常微小,以至于无论出于何种意图和目的,它都不会造成任何影响。尝试编写几个测试工具,并同时运行它们数百次,以平均循环完成时间为准,我们就会明白我的意思了。
从存储的角度来看,如果资源非常有限,那么嵌入式系统的堆栈很小,为慢速网络(例如GPRS等)而设计的有线协议等等,这可能是有意义的。
在32位计算机上使用Int32(在64位计算机上使用Int64)可获得最快的性能。如果我们确实担心它占用的空间,请使用较小的整数类型(不过可能会更慢)。
使用小于Int32的数据类型不会显着提高性能,实际上,我在某处读到,由于内存分配,使用Int32会比Int16快
在按索引循环遍历数组或者集合时,几乎应该始终使用Int32或者Int64(并且,不,我们不会通过使用UInt32或者UInt64来获得信誉)。
效率低下的最明显原因是BCL中找到的所有数组和集合索引都使用Int32,因此隐式强制转换总是会在试图使用Int16作为索引的代码中发生。
不太明显的原因(以及数组将" Int32"作为索引的原因)是CIL规范指出所有操作堆栈值都是" Int32"或者" Int64"。每次将值加载或者存储为任何其他整数类型("字节","字节"," UInt16"," Int16"," UInt32"或者" 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次。仅使用Int32或者Int64就可以完全避免它们。
更新:正如我在评论中所说,实际上,我现在已经写了一个有关该主题的博客文章,.NET集成数据类型和我们
根据以下参考,运行时可优化Int32的性能,并建议将它们用于计数器和其他频繁访问的操作。
从书中:MCTS自定进度培训工具包(考试70-536):Microsoft? .NET Framework 2.0应用程序开发基础
第1章:"框架基础"
第1课:"使用值类型"
Best Practices: Optimizing performance with built-in types The runtime optimizes the performance of 32-bit integer types (Int32 and UInt32), so use those types for counters and other frequently accessed integral variables. For floating-point operations, Double is the most efficient type because those operations are optimized by hardware.
另外,同一部分的表1-1列出了每种类型的建议用法。
与此讨论相关:
- Int16-互操作和其他特殊用途
- Int32-整数和计数器
- Int64-大整数