Ale*_*man 84
当按索引循环遍历数组或集合时,您几乎应该始终使用Int32或Int64(并且,不,您不会通过使用UInt32或获得信用UInt64).
效率较低的最明显的原因是在BCL中找到的所有数组和集合索引都采用Int32s,因此在尝试使用s作为索引的代码中总是会发生隐式转换Int16.
的不太明显原因(以及阵列采取的原因Int32作为指标)是,CIL说明书说,所有的操作栈的值是任一 Int32或Int64.每次任一负荷或值存储到任何其他整数型(Byte,SByte,UInt16,Int16,UInt32,或UInt64),有涉及的隐式转换的操作.无符号类型没有加载的惩罚,但是为了存储该值,这相当于截断和可能的溢出检查.对于签名类型,每个加载符号都会扩展,并且每个商店都会签名折叠(并且可能会进行溢出检查).
这对你最有害的地方是循环本身,而不是数组访问.例如,看看这个看似无辜的循环:
for (short i = 0; i < 32000; i++) {
...
}
Run Code Online (Sandbox Code Playgroud)
看起来不错吧?不!您基本上可以忽略initial(short i = 0),因为它只发生一次,但compare(i<32000)和incrementing(i++)部分发生了32000次.这里有一些pesudo代码,用于处理机器级别的内容:
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:
Run Code Online (Sandbox Code Playgroud)
其中有3次转换,运行32000次.而且只要使用Int32或者它们就可以完全避免它们Int64.
更新:正如我在评论中所说,我现在已经写了一篇关于这个主题的博客文章,.NET Integral Data Types和你
小智 52
根据以下参考,运行时优化Int32的性能,并为计数器和其他频繁访问的操作推荐它们.
从书中:MCTS Self-Paced Training Kit(考试70-536):Microsoft®.NETFramework 2.0-应用程序开发基础
第1章:"框架基础"
第1课:"使用值类型"
最佳实践:使用内置类型优化性能
运行时优化了32位整数类型(Int32和UInt32)的性能,因此将这些类型用于计数器和其他经常访问的整数变量.
对于浮点运算,Double是最有效的类型,因为这些操作是由硬件优化的.
此外,同一节中的表1-1列出了每种类型的推荐用途.与此讨论相关: