.NET Integer与Int16?

时间:2020-03-06 14:40:52  来源:igfitidea点击:

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

当我需要遍历一小部分计数限制在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-大整数