.NET Integer vs Int16?

时间:2008-09-24 18:44:51

标签: c# .net vb.net variables types

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

当我需要遍历计数限制在32000以下的项目的小列表时,我使用Int16作为我的 i 变量类型而不是{{1} }。我之所以这样做是因为我认为使用Integer比完全成熟Int16更有效。

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

10 个答案:

答案 0 :(得分:84)

您应该几乎总是使用Int32Int64(并且,不,您不会使用UInt32UInt64来获得积分当通过索引循环遍历数组或集合时。

效率较低的最明显的原因是在BCL中找到的所有数组和集合索引都需要Int32,因此隐式转换始终将在尝试的代码中发生使用Int16 s作为索引。

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

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

UInt64

看起来不错吧?不!您基本上可以忽略初始化(for (short i = 0; i < 32000; i++) { ... } ),因为它只发生一次,但比较(short i = 0)和递增(i<32000)部分发生了32000次。这里有一些pesudo代码,用于说明机器级别的内容:

i++

其中有 3 次转化 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: Int32

就可以完全避免这些问题

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

答案 1 :(得分:52)

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

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

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

  

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

     

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

     

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

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

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

答案 2 :(得分:11)

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

答案 3 :(得分:9)

反之亦然。

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

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

答案 4 :(得分:3)

任何性能差异在现代硬件上都会如此微小,无论从哪个角度来看,它都没有区别。尝试编写几个测试工具并运行它们几百次,取平均循环完成时间,你就会明白我的意思。

如果您的资源非常有限,那么从存储角度来看可能是有意义的 - 具有微小堆栈的嵌入式系统,为慢速网络设计的有线协议(例如GPRS等)等。

答案 5 :(得分:2)

永远不要假设效率。

从编译器到编译器以及平台到平台,有效性或不高效性会有所不同。除非你实际测试过这个,否则无法判断int16或int是否更有效。

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

答案 6 :(得分:2)

在32位计算机上使用Int32(或在64位计算机上使用Int64)以获得最快的性能。如果你真的担心它占用的空间(可能会慢一些),请使用较小的整数类型。

答案 7 :(得分:1)

这里的其他人都是正确的,只有使用小于 Int32(对于32位代码)/ Int64(对于64位代码),如果您需要它用于极端存储要求,或者用于其他级别对业务对象字段的强制执行(当然,在这种情况下,您仍应该进行有效级别的验证)。

一般情况下,在出现性能问题之前不要担心效率问题。在这种情况下,对其进行分析。如果猜测&amp;在分析时对两种方式进行检查对您没有帮助,请检查IL代码。

虽然好问题。您正在了解编译器如何做到这一点。如果你想学习更高效的编程,学习IL的基础知识以及C#/ VB编译器如何完成他们的工作将是一个好主意。

答案 8 :(得分:0)

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

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

当规格发生变化时,无论你计算什么 现在都超过32767并且你发现当你的应用程序开始抛出异常时,绝对不值得麻烦......

答案 9 :(得分:0)

使用小于Int32的数据类型没有显着的性能提升,事实上,我在某处读到由于内存分配,使用Int32将比Int16更快