在其他语言(如C ++)中,您必须自己跟踪数组长度 - Delphi如何知道数组的长度?是否有内部的隐藏整数?
对于性能关键部分,不使用Length()但是由我管理的直接整数会更好吗?
答案 0 :(得分:23)
有三种数组,每种数据的长度不同:
动态数组:这些是作为指针实现的。指针指向第一个数组元素,但该元素“后面”(在距数组起点的负偏移处)是两个额外的整数值,表示数组的长度和引用计数。 Length
读取该值。这与string
类型相同。
静态数组:编译器知道数组的长度,因此Length
是编译时常量。
打开数组:打开数组参数的长度作为单独的参数传递。编译器知道在哪里找到该参数,因此它将Length
替换为该参数值的读取。
答案 1 :(得分:5)
不要忘记动态数组的布局等会在64位版本的Delphi中发生变化,因此任何依赖于在特定偏移量处查找长度的代码都会破坏。
我建议只使用Length()
。如果你在循环中使用它,可能想要缓存它,但不要忘记for
循环已经缓存了循环的终止边界。
答案 2 :(得分:4)
是的,实际上还有两个带有动态数组的字段。第一个是数组中元素的数量,第四个元素偏移到第一个元素,而-8个字节偏移量就是引用计数。有关详细说明,请参阅Rudy's article。
对于第二个问题,您必须使用SetLength
来调整动态数组的大小,因此无论如何内部“长度”字段都可用。我认为没有太多用于额外的尺寸跟踪。
答案 3 :(得分:4)
自从Rob Kennedy对你问题的第一部分给出了如此好的答案,我将只讨论第二部分:
对于性能关键部分,不使用Length()但是由我管理的直接整数是否更好?
绝对不是。首先,正如Rob所提到的,编译器可以非常快速地访问信息,或者通过在动态的情况下读取数组开始之前的固定偏移量,在静态情况下使用编译时常量,并且在打开数组的情况下传递一个隐藏参数,你不会在性能上获得任何改进。
其次,由你管理的直接整数不会更快,但实际上会使用更多的内存(与Delphi一起分配的额外整数已经为动态和开放数组提供了,并且在这种情况下完全是一个额外的整数静态数组)。
即使你直接读取Delphi已经为动态数组存储的值,你也不会获得超过Length()的任何性能,并且如果数组的隐藏头的内部表示在将来发生变化,则会冒破坏代码的风险。
答案 4 :(得分:0)
是否存在内部隐藏整数
是
不使用Length()但是由我管理的直接整数?
没关系。
Dynamic arrays上的Addressing pointers文章中的Rudy Velthuis项目。
P.S。您还可以hit F1 button。