Eri*_*rom 34
虽然排序的解决方案:
(sort {$hash{$a} <=> $hash{$b}} keys %hash)[0]
Run Code Online (Sandbox Code Playgroud)
在其他一些答案中发现它非常优雅,它的表现不如它看起来那么好.首先,排序将O(n)
搜索搜索操作转换为O(n log n)
一个.其次,排序解决方案具有n log n
哈希查找.哈希查找起坐某些操作非常好,但与整个哈希工作时,看起坐会比使用速度较慢each
,keys
或values
通过数据结构进行迭代.这是因为迭代器不需要计算键的哈希值,也不需要反复遍历块来查找值.并且开销不是恒定的,而是随着哈希变大而增加.
以下是一些更快的解决方案:
use strict;
use warnings;
my %hash = (
small => 1,
medium => 5,
largest => 10,
large => 8,
tiny => 0.1,
);
Run Code Online (Sandbox Code Playgroud)
这是一个使用each
迭代器的解决方案(O(1)
操作完成n
次数):
sub largest_value (\%) {
my $hash = shift;
keys %$hash; # reset the each iterator
my ($large_key, $large_val) = each %$hash;
while (my ($key, $val) = each %$hash) {
if ($val > $large_val) {
$large_val = $val;
$large_key = $key;
}
}
$large_key
}
print largest_value %hash; # prints 'largest'
Run Code Online (Sandbox Code Playgroud)
或者是一个更快的版本,用于交换内存以获得速度(它会生成哈希的副本):
sub largest_value_mem (\%) {
my $hash = shift;
my ($key, @keys) = keys %$hash;
my ($big, @vals) = values %$hash;
for (0 .. $#keys) {
if ($vals[$_] > $big) {
$big = $vals[$_];
$key = $keys[$_];
}
}
$key
}
print largest_value_mem %hash; # prints 'largest'
Run Code Online (Sandbox Code Playgroud)
以下是各种散列大小的性能:
10 keys: Rate largest_with_sort largest_value largest_value_mem
largest_with_sort 111565/s -- -8% -13%
largest_value 121743/s 9% -- -5%
largest_value_mem 127783/s 15% 5% --
50 keys: Rate largest_with_sort largest_value largest_value_mem
largest_with_sort 24912/s -- -37% -40%
largest_value 39361/s 58% -- -6%
largest_value_mem 41810/s 68% 6% --
100 keys: Rate largest_with_sort largest_value largest_value_mem
largest_with_sort 9894/s -- -50% -56%
largest_value 19680/s 99% -- -12%
largest_value_mem 22371/s 126% 14% --
1,000 keys: Rate largest_with_sort largest_value largest_value_mem
largest_with_sort 668/s -- -69% -71%
largest_value 2183/s 227% -- -7%
largest_value_mem 2341/s 250% 7% --
10,000 keys: Rate largest_with_sort largest_value largest_value_mem
largest_with_sort 46.5/s -- -79% -81%
largest_value 216/s 365% -- -11%
largest_value_mem 242/s 421% 12% --
Run Code Online (Sandbox Code Playgroud)
正如您所看到的,如果内存不是问题,那么内部数组的版本最快,紧跟each
迭代器的版本,以及遥远的第三...sort
不知道为什么每个人都是手工做这个...
use List::Util qw( reduce );
my $max_val_key = reduce { $hash{$a} > $hash{$b} ? $a : $b } keys %hash;
Run Code Online (Sandbox Code Playgroud)
与排序哈希的其他答案相比,以下更节省空间并且将以O(n)而不是O(n log n)运行.它假定值是大于0的整数,并且散列不是空的,但应该很容易扩展为您的情况.
my $key_for_max_value;
my $max_value = -1;
while ((my $key, my $value) = each %hash) {
if ($value > $max_value) {
$max_value = $value;
$max_key = $key;
}
}
Run Code Online (Sandbox Code Playgroud)
$ key_for_max_value现在将是与最高值对应的键.