gpt4 book ai didi

Delphi 动态数组效率

转载 作者:行者123 更新时间:2023-12-03 15:39:09 27 4
gpt4 key购买 nike

我不是 Delphi 专家,我正在在线阅读有关动态数组和静态数组的信息。在 this 文章中,我找到了一个名为“Dynamic v. Static Arrays”的章节,其中有一段代码片段,作者在下面说:

[...] access to a dynamic array can be faster than a static array!



我知道动态数组位于堆上(它们是用引用/指针实现的)。

到目前为止,我知道动态数组的访问时间更好。但这与分配是一样的吗?就像我调用 SetLength(MyDynArray, 5) 比创建 MyArray = array[0..4] of XXX 慢?

最佳答案

So far I know that the access time is better on dynamic arrays.



那是不正确的。那篇文章中的陈述完全是错误的。

But is that the same thing with the allocation? Like if I called SetLength(MyDynArray, 5) is that slower than creating a MyArray = array[0..4] of XXX?



一个常见的谬误是静态数组是在堆上分配的。它们可以是全局变量,因此在加载模块时会自动分配。它们可以是局部变量并在堆栈上分配。它们可以通过调用 NewGetMem 动态分配。或者它们可以包含在复合类型(例如记录或类)中,因此以任何方式分配拥有对象。

明白了这一点,让我们考虑几个常见的情况。

局部变量,静态数组类型

如前所述,声明为局部变量的静态数组在堆栈上分配。分配是自动的,基本上是免费的。将分配视为由编译器执行(当它生成代码以保留堆栈帧时)。因此,分配没有运行时成本。访问可能会产生运行时成本,因为这可能会产生页面错误。不过,这一切都非常正常,如果您想使用固定大小的小数组作为局部变量,那么没有更快的方法来做到这一点。

类的成员变量,静态数组类型

同样,如上所述,分配是由包含对象执行的。静态数组是为对象保留的空间的一部分,当对象被实例化时,会在堆上分配足够的内存。堆分配的成本通常与要分配的块的大小无关。该语句的一个异常(exception)可能是非常大的块,但我假设您的数组的大小相对较小,只有数十或数百个字节。有了这些知识,我们可以再次看到分配成本基本上为零,因为我们已经为包含对象分配了内存。

局部变量,动态数组类型

动态数组由指针表示。所以你的局部变量是一个分配在堆栈上的指针。相同的参数适用于任何其他局部变量,例如上面讨论的静态数组类型的局部变量。分配基本上是免费的。不过,在对这个变量做任何事情之前,你需要通过调用 SetLength 来分配它。这会导致昂贵的堆分配。同样,当你完成后,你必须解除分配。

类的成员变量,动态数组类型

同样,动态数组指针的分配是免费的,但必须调用 SetLength 进行分配。那是堆分配。当对象被销毁时也需要重新分配。

结论

对于长度在编译时已知的小数组,使用静态数组会导致更有效的分配和释放。

请注意,我在这里只考虑分配。如果分配是用于处理对象的时间中相对微不足道的部分,那么此性能特征可能无关紧要。例如,假设数组在程序启动时分配,然后在程序运行期间重复使用。在这种情况下,访问时间支配分配时间,分配时间之间的差异变得微不足道。

另一方面,想象一个在程序生命周期内重复调用的短函数,假设这个函数是性能瓶颈。如果它在一个小数组上运行,那么使用动态数组的分配成本可能会很大。

你很少能用性能来制定严格而快速的规则。您需要了解这些工具的工作原理,并了解您的程序如何使用这些工具。然后,您可以形成关于哪些编码策略可能表现最佳的意见,然后您应该通过分析来测试这些意见。您会比您预期的更频繁地感到惊讶,因为您的直觉并不能很好地预测性能。

关于Delphi 动态数组效率,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44927185/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com