Delphi动态数组效率

Emm*_*oli 3 delphi

我不是德尔福专家,我在网上阅读有关动态数组和静态数组的内容.在文章中,我找到了一个叫章与代码段,下面笔者说:"动感V静态数组.":

[...]访问动态数组可能比静态数组更快!

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

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

Dav*_*nan 13

到目前为止,我知道动态数组的访问时间更长.

这是不正确的.该文中的陈述完全是错误的.

但这与分配是一回事吗?就像我打电话SetLength(MyDynArray, 5)比创建一个慢MyArray = array[0..4] of XXX

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

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

局部变量,静态数组类型

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

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

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

局部变量,动态数组类型

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

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

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

结论

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

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

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

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

  • 确实:分析是性能的必要途径. (4认同)