代码之家  ›  专栏  ›  技术社区  ›  devuxer

C中的array.getLength(dimension)实际如何工作?

  •  3
  • devuxer  · 技术社区  · 14 年前

    使用时 Array.GetLength(dimension) 在C中,数组的大小是在每次调用时都计算出来的,还是缓存/存储的大小和刚刚访问的值?

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

    4 回复  |  直到 14 年前
        1
  •  8
  •   Community CDub    7 年前

    在这里,自己开始缓存/优化无疑是一个坏主意。

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

    当优化器失去跟踪时,您将支付每次访问边界检查的罚款。

    这就是锯齿状阵列的原因( int[][] )比多亮度快( int[,] )优化 INT[[,] ] 只是不见了。不管怎样,在fx2之前,我还没有在fx4中检查这个状态。

    如果您想进一步研究这个问题,您建议的缓存通常称为' hoisting '长度属性。

        2
  •  0
  •   Brennan Vincent    14 年前

    它可能是在编译时插入的,如果知道的话。否则,存储在变量中。如果不是的话,怎么计算尺寸呢?

    但是,您不应该对框架的内部操作进行假设。如果你想知道某件事是否或多或少有效率,测试一下吧!

        3
  •  0
  •   Guffa    14 年前

    如果您确实需要尽可能快的循环,那么可以将长度存储在变量中。这将使您的性能略有提高,我做的一些快速测试表明它大约快了30%。

    由于差别不大,这表明 GetLength 方法真的很快。除非你真的需要把最后一个代码塞进代码,否则你应该在循环中使用这个方法。

    这只适用于多维数组。对于一维数组,使用 Length 在循环中使用数组时,作为优化程序的属性可以移除边界检查。

        4
  •  -1
  •   Jason Williams    14 年前

    命名约定是一条线索。.NET中的“length”方法(例如array.length)通常返回一个已知值,而“count”方法(例如list.count)将/可能枚举集合的内容以计算项目数。(在后面的.nets中,有类似any的扩展方法,允许您检查集合是否为非空,而不必使用可能代价高昂的count操作)getlength只能与长度不同,因为您可以请求所需长度的维度。

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

    (但是,编写几个循环并给它们计时(使用高性能计数器)很容易,以了解不同的调用/类型对执行速度的影响。做这种快速测试是一种很好的方法,它可以让你深入了解一种语言,如果你只是阅读答案,那么你可能不会真正接受这种语言。)