File: benchmark.pl

package info (click to toggle)
libhash-safekeys-perl 0.04-1
  • links: PTS, VCS
  • area: main
  • in suites: bookworm, forky, sid, trixie
  • size: 112 kB
  • sloc: perl: 220; makefile: 3
file content (128 lines) | stat: -rw-r--r-- 4,169 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
use Benchmark ':all';
use lib 'blib/lib', 'blib/arch';
use Hash::SafeKeys;
use Hash::StoredIterator qw(hash_get_iterator hash_set_iterator hkeys);
use Time::HiRes;
use strict;
use warnings;


# http://stackoverflow.com/questions/10921221/
#    can-i-copy-a-hash-without-resetting-its-each-iterator
#    ?noredirect=1#comment63376080_10921221
# proposes Hash::StoredIterator as faster than Hash::SafeKeys
#
# and how does Hash::SafeKeys perform with large hashes ?


my $t0 = Time::HiRes::time;
my %hash = (
    "aaaaa" .. "aczzz",
    foo => 123,
    bar => "456",
    baz => [ 3, 17, "Alpha", { "Bravo" => "Charlie", "Delta" => "Echo" },
	     [ "Foxtrot", "Golf", "Hotel" ], *STDERR,
	     sub { my($i,$j,$k) = @_; return 42*$i+$j/$k; } ],
    quux => { "Lima" => "Mike",
	      "November" => *Oscar,
	      "Papa" => sub { "Quebec" },
	      "Romeo" => [ qw(Sierra Tango Uniform) ],
	      "Victor" => { "Whiskey" => { "X-ray" => "Yankee" } },
	      "Zulu" => undef }
    );
close *Oscar if 0; # suppress "used only once" warning
my $t1 = Time::HiRes::time;

print "Size of test hash is ", scalar keys %hash, "\n";
printf "Setup time was %.3fs\n", $t1-$t0;

my $rlist = timethese(1000, {
    builtin => sub {
        my @x = keys %hash;
    },
    safekeys => sub { 
        my @x = safekeys %hash;
    },
    storediter1 => sub {
        my $hi = hash_get_iterator(\%hash);
        my @x = keys %hash;
        hash_set_iterator(\%hash,$hi);
    },
    storediter2 => sub {
        my @x = hkeys %hash;
    },
    saverestore => sub {
        my $hi = Hash::SafeKeys::save_iterator_state(\%hash);
        my @x = keys %hash;
        Hash::SafeKeys::restore_iterator_state(\%hash, $hi);
    },
} );

# scalar context
my $rscalar = timethese(1000, {
    builtinSC => sub {
        my $x = keys %hash;
    },
    storediter1SC => sub {
        my $hi = hash_get_iterator(\%hash);
        my $x = keys %hash;
        hash_set_iterator(\%hash,$hi);
    },
    safekeysSC => sub { 
        my $x = safekeys %hash;
    },
    storediter2SC => sub { my $x = hkeys %hash },
    saverestoreSC => sub {
        my $hi = Hash::SafeKeys::save_iterator_state(\%hash);
        my $x = keys %hash;
        Hash::SafeKeys::restore_iterator_state(\%hash, $hi);
    },
                        });

cmpthese( $rscalar );
cmpthese( $rlist );

exit;

__END__

Results:

Hash::SafeKeys v0.03 - Hash::StoredIterator v0.007, 26_368 keys

SCALAR           Rate  safekeysSC  storediter2SC builtinSC storediter1SC
safekeysSC       50.9/s        --            -1%     -100%         -100%
storediter2SC    51.5/s        1%             --     -100%         -100%
builtinSC        Inf/s       Inf%           Inf%        --            0%
storediter1SC    Inf/s       Inf%           Inf%        0%            --

LIST             Rate    safekeys storediter2     builtin storediter1
safekeys       28.0/s          --         -2%        -62%        -63%
storediter2    28.5/s          2%          --        -62%        -62%
builtin        74.4/s        165%        161%          --         -1%
storediter1    75.3/s        169%        164%          1%          --


TL;DR:
     custom keys method is 3 times costlier than native
     stored iterator + native keys does not have a performance drop-off
     scalar call on custom keys method is expensive

-----

Hash::SafeKeys v0.04 - Hash::StoredIterator v0.007, 26_368 keys

SCALAR            Rate  storediter2SC safekeysSC builtinSC storediter1SC
storediter2SC   62.0/s             --      -100%     -100%         -100%
safekeysSC       Inf/s           Inf%         --        0%            0%
builtinSC        Inf/s           Inf%         0%        --            0%
storediter1SC    Inf/s           Inf%         0%        0%            --

LIST           Rate    safekeys storediter2 storediter1     builtin
safekeys     33.4/s          --         -1%        -62%        -63%
storediter2  33.7/s          1%          --        -62%        -63%
storediter1  88.0/s        164%        161%          --         -3%
builtin      90.6/s        171%        169%          3%          --

TL;DR:
     scalar custom keys call is now cheap in Hash::SafeKeys