【问题标题】:Does a hash shrink in Perl as you delete elements?当您删除元素时,Perl 中的哈希值会缩小吗?
【发布时间】:2010-09-12 22:18:06
【问题描述】:

当您删除元素时,Perl 中的哈希是否会缩小。

更具体地说,我有一个我继承的 perl 程序,它可以解析一个巨大的文件 (1 GB) 并加载一个哈希值。它会对另一个文件做同样的事情,然后比较不同的元素。在这个过程中内存消耗很大,即使我添加了删除哈希元素,但它们被使用了,内存消耗似乎没有受到影响。

脚本非常慢,而且占用大量内存。我知道它设计得不好,但是关于哈希内存使用的任何想法?

【问题讨论】:

    标签: performance perl


    【解决方案1】:

    解决方法:派生一个分配所有内存的子进程。当它完成它的事情时,让它传回一些聚合信息;当分叉的进程死亡时,它的内存将随之消失。有点痛苦,但适用于某些情况。例如,如果您正在处理许多文件,每次处理一个文件,只有少数文件很大,并且需要保留很少的中间状态。

    【讨论】:

      【解决方案2】:

      关于具体问题:不,删除哈希键不会减少程序的内存消耗。

      关于更一般的情况:绝大多数程序和语言将继续保留它们以前使用但当前未使用的内存。这是因为操作系统请求分配内存是一个相对较慢的操作,所以他们保留它以防以后再次需要它。

      因此,如果您想改善这种情况,您需要减少程序所需的峰值内存量,无论是通过修改您的算法以不再需要一次访问尽可能多的数据,通过使用 on-磁盘存储(例如前面提到的 DBM::Deep),或者通过将不需要的变量的空间释放回 perl(让它们超出范围或将它们设置为 undef),以便可以重用。

      【讨论】:

        【解决方案3】:

        如果第二个文件中的输入只需要一次(在读取时),您可能会将内存使用量减少一半。

        根据您的算法,您甚至可以在内存中同时保持打开的文件句柄和未使用值的小散列值。一个示例是排序数据的合并或比较 - 您只需保留每个文件中的当前行并在执行过程中将其相互比较,向前跳过直到 cmp 更改。

        另一种方法可能是进行多次传递,尤其是当您的机器中有一个或多个空闲内核时。打开读取管道并让子进程以可管理的预组织块的形式为您提供数据。

        对于更通用的算法,你只能通过以磁盘速度为代价来避免为内存大小买单。

        在大多数情况下,将每个数据源加载到内存中只会节省开发时间 - 然后当 N 变大时,您会为占用空间和/或速度付出代价。

        【讨论】:

          【解决方案4】:

          如果你的散列真的很大,一个更好的策略是可能使用磁盘上的散列,让操作系统担心把东西进出内存。我特别喜欢 Berkeley DB 在磁盘上存储大哈希,Perl BerkeleyDB 模块提供了一个功能齐全的接口,包括一个绑定的 API。

          DBM::Deep 也可以用作插入式哈希替换,但依赖于它自己的格式。如果您的结构需要由其他(非 Perl)系统读取,这可能会很痛苦。

          【讨论】:

            【解决方案5】:

            您可能想查看DBM::Deep 之类的内容。它完成了迈克尔提到的那些捆绑的事情,所以你不必考虑它。一切都存储在磁盘上而不是内存中。它只是需要一个更高级的数据库服务器。

            此外,如果您想追踪性能瓶颈,请查看 Devel::NYTProf,这是来自纽约 Times 的 Perl 分析的新热点。

            【讨论】:

              【解决方案6】:

              一般来说,Perl 不能将内存返回给操作系统。不过,它可能能够在内部重用内存,这可以减少程序所需的内存量。

              见 perlfaq3:How can I free an array or hash so my program shrinks?

              如果哈希使用的内存过多(即 > 物理内存),您可以 tie 将它们写入磁盘上的文件。这将大大减少您的内存使用量,但请注意访问磁盘上的结构比访问内存中的结构要慢得多。 (磁盘抖动也是如此。)

              【讨论】:

                猜你喜欢
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 2013-03-30
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 2012-04-28
                相关资源
                最近更新 更多