如何对包含大量数据的Perl哈希进行排序?

syk*_*ker 2 sorting perl hash

我在Perl中对哈希进行排序.运行我的Perl脚本时遇到内存不足错误:

foreach $key (sort (keys(%hash))) {
   ....
}
Run Code Online (Sandbox Code Playgroud)

如何对包含大量数据的哈希进行排序?

Sch*_*ern 13

sort keys %hash%hash在内存方面,它对于一个大的是低效的,它大致相当于:

my @keys = keys %hash;
@keys = sort @keys;
Run Code Online (Sandbox Code Playgroud)

因为它必须在进行排序时将三个密钥副本保留在内存中(一个在散列中,一个在键列表中,一个在创建的排序列表中). foreach迭代器的内存优化不适用.

由于哈希是如此之大,最好的选择是让它完全没有内存.将其粘贴在BerkeleyDB文件中.如果你想保持密钥的顺序,哈希不是最好的选择,树就是.我建议使用Berkeley BTree文件.树将有效地保持您的数据像数组一样排序,同时提供像哈希快速查找.

这是使用BerkeleyDB的一个例子. DB_File更简单,文档更好,但没有利用BerkeleyDB的现代功能.因人而异.

use BerkeleyDB;

my $db  = tie my %hash, 'BerkeleyDB::Btree',
              -Filename => "your.db",
              -Compare  => sub { $_[1] cmp $_[0] },
              -Flags    => DB_CREATE;
Run Code Online (Sandbox Code Playgroud)

-Compare说明如何提供自己的排序功能.绑定的界面将是缓慢的.除非您需要它像哈希一样,否则请使用对象接口.

  • "@ary = sort @ary"是特别的核心内容.它*做*就地排序,不要介意语法.参看 例如2004年的核心提交fe1bc4cf71e7b04d33e679798964a090d9fa7b46.复制,然后排序并不是一个建议,就像我刚刚发现自己发现的好奇心,当我意识到@ ary2 = sort @ary是*更糟糕的记忆.无论哪种方式,我认为你的躺椅类比适用.:) (2认同)