c# - .NET 整数与 Int16?

标签 c# .net vb.net variables types

我的编码习惯有问题。

当我需要遍历计数限制低于 32000 的一小部分项目时,我使用 Int16 作为我的 i 变量类型而不是 Integer。我这样做是因为我假设使用 Int16 比完全成熟的 Integer 更有效。

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

最佳答案

你应该几乎总是使用Int32Int64 (而且,不,在按索引遍历数组或集合时,您不会通过使用 UInt32UInt64 获得积分。

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

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

这对您伤害最大的地方是循环本身,而不是数组访问。以这个看似无辜的循环为例:

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

关于c# - .NET 整数与 Int16?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/129023/

相关文章:

c# - 如何在 Visual Studio 2013 中的 C# 结构字段上设置断点

c# - 通过 MouseBinding 将鼠标事件与 ViewModel 连接

c# - 什么可能导致(托管)UIAutomation 在枚举子级时获得 self 引用

c# - 如何配置 Fluent NHibernate 以将查询输出到 Trace 或 Debug 而不是控制台?

vb.net - 是否有任何工具可以为 Visual Studio 2008/2005 转换多行文本?

xml - 读取具有多个命名空间的子节点

c# - 如何在 IClassifier.GetClassificationSpans 上获取行号?

c# - 使用最小配置的 Unity

.net - 如何从 App.Config 文件设置 CultureInfo.CurrentCulture?

vb.net - 如何在不同线程中调用的窗体上设置Windows标题?