当前位置 : 主页 > 编程语言 > delphi >

Delphi动态数组效率

来源:互联网 收集:自由互联 发布时间:2021-06-23
我不是德尔福专家,我在网上阅读有关动态数组和静态数组的内容.在 this文章中,我找到了一个名为“Dynamic v.Vatic Arrays”的章节,其中包含一个代码片段,作者在下面说: […] access to a dyn
我不是德尔福专家,我在网上阅读有关动态数组和静态数组的内容.在 this文章中,我找到了一个名为“Dynamic v.Vatic Arrays”的章节,其中包含一个代码片段,作者在下面说:

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

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

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

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?

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

说清楚之后,让我们考虑一些常见的情况.

局部变量,静态数组类型

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

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

同样,如上所述,分配由包含对象执行.静态数组是为对象保留的空间的一部分,当实例化对象时,在堆上分配了足够的内存.堆分配的成本通常不会很大程度上取决于要分配的块的大小.该语句的一个例外可能是非常大的块,但我假设你的数组大小相当小,数十或数百个字节.有了这些知识,我们可以再次看到,分配成本基本上为零,因为我们已经为包含对象分配了内存.

局部变量,动态数组类型

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

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

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

结论

对于在编译时已知长度的小数组,使用静态数组可以实现更高效的分配和释放.

请注意,我只考虑在此分配.如果分配是使用对象所花费时间的相对不重要的部分,那么这种性能特征可能无关紧要.例如,假设在程序启动时分配数组,然后在程序的持续时间内重复使用.在这种情况下,访问时间主导分配时间,并且分配时间之间的差异变得无关紧要.

另一方面,想象一下在程序生命周期中反复调用的一个简短函数,让我们假设这个函数是性能瓶颈.如果它在小型阵列上运行,那么使用动态阵列的分配成本可能很大.

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

网友评论