line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
3
|
|
|
3
|
|
70557
|
use strict; |
|
3
|
|
|
|
|
6
|
|
|
3
|
|
|
|
|
127
|
|
2
|
3
|
|
|
3
|
|
20
|
use warnings; |
|
3
|
|
|
|
|
4
|
|
|
3
|
|
|
|
|
308
|
|
3
|
|
|
|
|
|
|
package Sort::HashKeys; |
4
|
|
|
|
|
|
|
|
5
|
|
|
|
|
|
|
# ABSTRACT: Get a sorted-by-key list from a hash |
6
|
|
|
|
|
|
|
our $VERSION = '0.005'; # VERSION |
7
|
|
|
|
|
|
|
|
8
|
|
|
|
|
|
|
require XSLoader; |
9
|
|
|
|
|
|
|
XSLoader::load('Sort::HashKeys', $VERSION); |
10
|
|
|
|
|
|
|
|
11
|
|
|
|
|
|
|
=pod |
12
|
|
|
|
|
|
|
|
13
|
|
|
|
|
|
|
=encoding utf8 |
14
|
|
|
|
|
|
|
|
15
|
|
|
|
|
|
|
=head1 NAME |
16
|
|
|
|
|
|
|
|
17
|
|
|
|
|
|
|
Sort::HashKeys - Get a sorted-by-key list from a hash |
18
|
|
|
|
|
|
|
|
19
|
|
|
|
|
|
|
|
20
|
|
|
|
|
|
|
=head1 SYNOPSIS |
21
|
|
|
|
|
|
|
|
22
|
|
|
|
|
|
|
use Sort::HashKeys; |
23
|
|
|
|
|
|
|
|
24
|
|
|
|
|
|
|
my %hash; |
25
|
|
|
|
|
|
|
|
26
|
|
|
|
|
|
|
@sorted_1 = map { ($_, $hash{$_}) } sort keys %hash; |
27
|
|
|
|
|
|
|
@sorted_2 = Sort::HashKeys::sort(%hash); |
28
|
|
|
|
|
|
|
# Same outcome, but the second is faster |
29
|
|
|
|
|
|
|
|
30
|
|
|
|
|
|
|
=head1 DESCRIPTION |
31
|
|
|
|
|
|
|
|
32
|
|
|
|
|
|
|
[13:37:51] Is there a better way to get a sorted list out of a hash |
33
|
|
|
|
|
|
|
than map { ($_, $versions{$_}) } reverse sort keys @versions |
34
|
|
|
|
|
|
|
or iterating manually? |
35
|
|
|
|
|
|
|
[13:39:06] oh I could provide a compare function to sort and chunk the |
36
|
|
|
|
|
|
|
list two by two.. |
37
|
|
|
|
|
|
|
[13:40:15] i'd probably go with the map{} reverse sort keys |
38
|
|
|
|
|
|
|
[13:41:04] I don't like it that it repeats the lookup for all keys. |
39
|
|
|
|
|
|
|
Of course wouldn't matter in practice but still… |
40
|
|
|
|
|
|
|
[13:43:40] whatever other solution you find will be slower |
41
|
|
|
|
|
|
|
[13:49:05] put it into a list, pass it to XS, run qsort(3) over it |
42
|
|
|
|
|
|
|
with double the element size. and compare taking only the |
43
|
|
|
|
|
|
|
first part into account. return it back? |
44
|
|
|
|
|
|
|
|
45
|
|
|
|
|
|
|
=head1 BENCHMARK |
46
|
|
|
|
|
|
|
|
47
|
|
|
|
|
|
|
See L in this distribution. Test was run on a Haswell 2.6 GHz i5 CPU (4278U) for a minute each on a copy of a randomly generated hash of 1000 keys. Keys were alphanumeric with length between 1 and 6 and values of integers between 1 and 1000. |
48
|
|
|
|
|
|
|
|
49
|
|
|
|
|
|
|
# perl-5.24.0 w/ BSD libc |
50
|
|
|
|
|
|
|
Rate |
51
|
|
|
|
|
|
|
map {($_,$h{$_})} sort keys %h 1589/s -- -28% -32% -33% |
52
|
|
|
|
|
|
|
S::HK::sort(%h) w/ qsort (threaded) 2199/s 38% -- -6% -7% |
53
|
|
|
|
|
|
|
S::HK::sort(%h) w/ qsort_r (threaded) 2338/s 47% 6% -- -2% |
54
|
|
|
|
|
|
|
S::HK::sort(%h) w/ qsort (non-threaded) 2375/s 49% 8% 2% -- |
55
|
|
|
|
|
|
|
|
56
|
|
|
|
|
|
|
49% faster on non-threaded Perl and up to 47% faster on threaded Perl. |
57
|
|
|
|
|
|
|
|
58
|
|
|
|
|
|
|
The Slowdown with C on threaded build is because the interpreter state is fetched from thread local storage on every comparison. On GNU and BSD systems, this is avoided by using non-standard C, which allows passing an extra parameter to the comparison function. |
59
|
|
|
|
|
|
|
|
60
|
|
|
|
|
|
|
=head1 METHODS AND ARGUMENTS |
61
|
|
|
|
|
|
|
|
62
|
|
|
|
|
|
|
=over 4 |
63
|
|
|
|
|
|
|
|
64
|
|
|
|
|
|
|
=item sort(@) |
65
|
|
|
|
|
|
|
|
66
|
|
|
|
|
|
|
Sorts a hash-like list C<< (key1 => val1, key2 => val2>) >> by means of your libc's |
67
|
|
|
|
|
|
|
L in ascending order according to Perl's internal C function. |
68
|
|
|
|
|
|
|
|
69
|
|
|
|
|
|
|
Unlike Perl's built-in L. C is not required to be a stable sort and providing a custom comparison function is not yet supported. |
70
|
|
|
|
|
|
|
|
71
|
|
|
|
|
|
|
Lists with odd number of elements are padded by an C. |
72
|
|
|
|
|
|
|
|
73
|
|
|
|
|
|
|
=item reverse_sort(@) |
74
|
|
|
|
|
|
|
|
75
|
|
|
|
|
|
|
Sorts in descending order. |
76
|
|
|
|
|
|
|
|
77
|
|
|
|
|
|
|
=cut |
78
|
|
|
|
|
|
|
|
79
|
|
|
|
|
|
|
1; |
80
|
|
|
|
|
|
|
__END__ |