【问题标题】:What is the use of preallocating memory for an array in perl?在 perl 中为数组预分配内存有什么用?
【发布时间】:2016-08-15 00:40:10
【问题描述】:

Perl 允许预分配数组。我们可以在使用前预先分配数组,然后我们可以添加更多元素。例如,分配 50 个数组成员然后添加第 51 个成员,因为数组是可扩展的。那么预分配数组会提高性能吗?

【问题讨论】:

    标签: arrays perl


    【解决方案1】:

    这是因为计算机中内存的分配方式。计算机内存就像白板上的空间:它相对于其他内存有一个位置;不能移动,必须复制。

    如果你创建一个小数组,它可能看起来像这样:

    @array = (1, 4, 8, 12, 19);
    
    allocate memory for @array
    ______________________|               |______| a b c|__________
    
    copy in the data
    ______________________|  1  4  8 12 19|______| a b c|__________
    

    _ 是未分配的内存。 | 表示分配给数组的范围。 | a b c| 是其他数组。

    然后,如果您向该数组推送几次,Perl 将不得不重新分配内存。在这种情况下,它可以将它已经拥有的内存增长到未分配的空间中。

    push @array, 23, 42;
    
    grow the existing memory
    ______________________|  1  4  8 12 19      | a b c|__________
    
    add the new data
    ______________________|  1  4  8 12 19 23 42| a b c|__________
    

    现在,如果您将更多数字推送到@array,会发生什么?它不能再增加你的记忆了,还有另一个数组在路上。因此,就像在白板上一样,它必须将整个数组复制到一块清晰的内存中。

    push @array, 85, 99;
    
    Allocate a new chunk of memory
    |                           |  1  4  8 12 19 23 42| a b c|__________
    
    Copy the existing data
    |  1  4  8 12 19 23 42      |  1  4  8 12 19 23 42| a b c|__________
    
    Deallocate the old memory
    |  1  4  8 12 19 23 42      |__1__4__8_12_19_23_42| a b c|__________
    
    Add the new data
    |  1  4  8 12 19 23 42 85 99|__1__4__8_12_19_23_42| a b c|__________
    

    为了节省时间,Perl 不会费心擦除旧数据。它只会释放它,其他东西可以在需要时在它上面乱写。

    这使得推送变得更加昂贵,尤其是对于需要复制更多数据的非常大的数组。随着您的数组变得越来越大,Perl 将不得不分配新的内存块并复制所有内容的可能性越来越大。

    还有一个问题:内存碎片。如果您一遍又一遍地分配和重新分配,那么大块内存可能会被切碎,因此很难找到大块可用内存。这在现代操作系统上不是问题,但仍然是一个问题。它会使您的内存看起来比实际内存少,并且可能导致操作系统将磁盘用作内存(虚拟内存)的次数超出应有的程度。磁盘比内存慢。


    我简化了很多事情。我让它看起来每次你push时Perl都必须重新分配。这不是真的。由于这个原因,Perl 为数组分配的内存比它需要的多。因此,您可以安全地向数组中添加一些额外的条目,而无需 Perl 重新分配。字符串和哈希也是如此。

    另一件事是,对于现代操作系统上内存分配的工作原理,这可能是一个有点过时的观点……尽管如果 Perl 不信任操作系统,它有时会自己进行内存分配。检查use Config; print $Config{usemymalloc}n 表示 Perl 正在使用操作系统的内存分配,y 表示它正在使用 Perl。

    经验法则是:不要预先分配,这可能会浪费您的时间和计算机的内存。但是,如果以下条件所有都为真,请查看预分配是否有帮助。

    • profiled发现了一个问题。
    • 您正在通过添加增量来构建数据结构。
    • 您肯定知道它的最小最终尺寸。
    • 那个尺寸是“大”的。

    什么是“大”有待商榷,取决于您的 Perl 版本、操作系统、硬件和性能容差。

    【讨论】:

      猜你喜欢
      • 2021-04-16
      • 1970-01-01
      • 2013-11-24
      • 1970-01-01
      • 2015-12-05
      • 2020-05-31
      • 2018-08-24
      • 1970-01-01
      • 2014-03-04
      相关资源
      最近更新 更多