看着这个问题:Why does a C/C++ compiler need know the size of an array at compile time ?我想到编译器实现者应该有一些时间来弄清楚(这是10年前C99标准的一部分)并提供有效的实现。

但是,从答案看,它似乎仍然被认为是昂贵的。

这使我感到惊讶。

当然,我了解到静态偏移在性能上要比动态偏移好得多,并且与一种建议不同,我实际上不会让编译器执行数组的堆分配,因为这可能会花费更多的费用(被测量;)]

但是我仍然对预期的成本感到惊讶:

  • 如果一个函数中没有VLA,那么据我所知,不会有任何成本。
  • 如果只有一个VLA,则可以将其放在所有变量之前或之后,因此可以为大多数堆栈帧获取静态偏移量(在我看来,这似乎是对的,但我并不精通堆栈管理)

  • 当然,存在多个VLA的问题,我想知道是否有专用的VLA堆栈会起作用。这意味着,VLA将由一个计数和一个指针(因此具有已知大小)和实际用于第二个堆栈的内存(仅用于此目的)表示。

    [改写]

    如何在gcc/VC++中实现VLA?

    成本真的那么可观吗?

    [结束改写]

    在我看来,即使使用当前的实现,它也仅比使用vector更好,因为您无需承担动态分配的开销(不会调整大小)。

    编辑:

    存在一个部分响应here,但是将VLA与传统数组进行比较似乎不公平。如果我们事先知道大小,则不需要VLA。在相同的问题中,AndreyT给出了有关实现的一些提示,但是它并不像我所希望的那样精确。

    最佳答案



    AFAIK VC++未实现VLA。这是一个C++编译器,仅支持C89(无VLA,无限制)。我不知道gcc如何实现VLA,但是最快的方法是将指向VLA及其大小的指针存储在堆栈帧的静态部分中。这样,您可以访问具有恒定大小数组性能的VLA(如果堆栈像x86中那样向下增长,则是最后一个VLA(取消引用[堆栈指针+索引*元素大小+最后一次临时推送的大小]),以及第一个VLA向上增长(取消引用[stackframe指针+与stackframe的偏移量+索引*元素大小]))。所有其他VLA都将需要一个间接寻址来从堆栈的静态部分获取其基址。

    [编辑:同样,在使用VLA时,编译器不能忽略基于堆栈框架的指针,否则,这是多余的,因为可以在编译时计算出与堆栈指针的所有偏移量。因此,您的免费注册减少了。 —结束编辑]



    并不是的。此外,如果您不使用它,则无需为此付费。

    [编辑:可能更正确的答案是:与什么相比?与堆分配 vector 相比,访问时间将相同,但分配和释放将更快。 —结束编辑]

    关于c++ - C++中的可变长度数组开销?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/4343850/

    10-09 07:34