C#中的Array.GetLength(维度)如何实际工作?

时间:2010-07-04 21:29:43

标签: c# arrays

在C#中使用Array.GetLength(dimension)时,每次调用数组时实际上是否计算了数组的大小,或者是否缓存/存储了该数组的大小并且该值才被访问?

我真正想知道的是,如果将一个局部变量设置为数组维度的长度,如果在一个大循环中使用,或者我可以一遍又一遍地调用array.GetLength(),则会增加任何效率o任何速度惩罚。

4 个答案:

答案 0 :(得分:8)

在这里开始缓存/优化肯定是一个坏主意。

处理数组时,必须遵循(JIT)优化器可以识别的标准路径。如果这样做,不仅会缓存Length属性,更重要的是索引边界检查可以在循环之前完成一次。

当优化程序丢失您的踪迹时,您将支付每次访问边界检查的罚款。

这就是为什么锯齿状数组(int[][])比多维数(int[,])更快的原因。简化int[,]的优化。无论如何,我还没有检查Fx4的状态。

如果您想进一步研究,您建议的缓存通常称为“hoisting”长度属性。

答案 1 :(得分:0)

如果已知,它可能在编译时插入。否则,存储在变量中。如果不是,那么如何计算尺寸?

但是,您不应该对框架的内部操作做出假设。如果你想知道某些东西是效率更高还是更低,请测试它!

答案 2 :(得分:0)

如果您确实需要尽可能快地循环,则可以将长度存储在变量中。这会给你带来轻微的性能提升,我做的一些快速测试表明它的速度提高了约30%。

由于差异不大,它表明GetLength方法非常快。除非你真的需要填写代码的最后一个,否则你应该只使用循环中的方法。

仅适用于多维数组。对于单维数组,在循环中使用Length属性实际上更快,因为优化器可以在循环中使用数组时删除边界检查。

答案 3 :(得分:-1)

命名约定是一个线索。 .net中的“Length”方法(例如Array.Length)通常返回已知值,而“Count”方法(例如List.Count)将/可以枚举集合的内容以计算项目数。 (在后面的.nets中有像Any这样的扩展方法,允许你检查集合是否为非空而不必使用可能很昂贵的Count操作)GetLength只应该与Length不同,因为你可以请求你想要长度的维度的。

局部变量在调用GetLength时不太可能有任何区别 - 编译器无论如何都会很好地优化大多数情况 - 或者你可以使用foreach,它不需要在开始之前确定长度。

(但是很容易编写几个循环并计时(使用高性能计数器)来查看不同的调用/类型对执行速度的影响。这种快速测试可以很好如果您只是阅读答案,那么获得对您可能不会真正接受的语言的见解的方式)