```
##
7 +----------------------------------------------------------------------+
| + + + |
| 'arr2' A |
6 |-+ 'hash2' BB +-|
| B B |
| B |
| B B |
5 |-+ +-|
S | B B |
E | B |
C4 |-+ B B +-|
O | B |
N | B |
D3 |-+ B B +-|
S | B A A A |
| B B A A A |
| B A A A |
2 |-+ A A A +-|
| A A A |
| A A A + + + |
1 +----------------------------------------------------------------------+
10000 15000 20000 25000 30000
number of items
##
```

```
##
use strict;
use warnings;
use Benchmark qw/timeit :hireswallclock/;
my $num_repeats = 50;
my @bobjs;
my %ahash;
my @anarray;
my @results;
my $linreg;
# map { $_ * 1000 } 10..30 simulates a loop with step of 1000
# Do array inserts
@results = ();
@bobjs = ();
@anarray = ();
for my $num_inserts ( map { $_ * 1000 } 10..30 ){
# warmup
do_array_inserts($num_inserts, \@anarray); @anarray = ();
# time it
my $abobj = timeit($num_repeats,
sub { do_array_inserts($num_inserts, \@anarray); @anarray = (); }
);
push @bobjs, [$num_inserts, $abobj];
push @results, [$num_inserts, $abobj->real];
print $num_inserts." array insertions took ". $abobj->real . " seconds.\n"
}
$linreg = ordinary_least_squares(@results);
print "Array inserts:\n";
print "Y = ".$linreg->{A}." * X + ".$linreg->{B}." with error ".$linreg->{E}."\n";
print "Y : total time to insert X elements.\n";
# Do hash inserts
@results = ();
%ahash = ();
@bobjs = ();
for my $num_inserts ( map { $_ * 1000 } 10..30 ){
# warmup
do_hash_inserts($num_inserts, \%ahash); %ahash = ();
# time it
my $abobj = timeit($num_repeats,
sub { do_hash_inserts($num_inserts, \%ahash); %ahash = (); }
);
push @bobjs, [$num_inserts, $abobj];
push @results, [$num_inserts, $abobj->real];
print $num_inserts." hash insertions took ". $abobj->real . " seconds.\n"
}
$linreg = ordinary_least_squares(@results);
print "Hash inserts:\n";
print "Y = ".$linreg->{A}." * X + ".$linreg->{B}." with error ".$linreg->{E}."\n";
print "Y : total time to insert X elements.\n";
#### end
sub do_hash_inserts {
my ($repeats, $container) = @_;
for (1..$repeats){
$container->{random_key()} = random_value();
}
}
sub do_array_inserts {
my ($repeats, $container) = @_;
for (1..$repeats){
push @$container, random_value();
}
}
sub random_key {
return join '', map { rand } 1..3
}
sub random_value {
return join '', map { rand } 1..3
}
sub ordinary_least_squares {
# each element of input array is [num_insertions, time_seconds]
my @observations = @_;
# coefficients to find assuming Y = A*X + B
my ($A, $B);
my $diff;
my $num_observations = @observations;
my $cov = 0.0;
my $var = 0.0;
my $meanx = 0.0;
my $meany = 0.0;
for my $anobs (@observations){
my ($x, $y) = @$anobs;
$meanx += $x;
$meany += $y;
}
$meanx /= $num_observations;
$meany /= $num_observations;
for my $anobs (@observations){
my ($x, $y) = @$anobs;
my $diffx = ($x - $meanx);
$cov += $diffx * ($y - $meany);
$var += $diffx * $diffx;
}
$A = $cov / $var;
$B = $meany - $A * $meanx;
my $error = 0.0;
for my $anobs (@observations){
my ($x, $y) = @$anobs;
my $ypred = $A * $x + $B;
$error += ($y - $ypred)**2
}
$error = sqrt($error) / $num_observations;
return { A => $A, B => $B, E => $error }
}
```