二つの配列からハッシュを作成するベンチマーク
· 2 min read
昔に作ったファイルを見ていて、よくわからないコードが出てきたので調べた。
それは、ハッシュのスライスだった。
未だに覚えられないのは、やはりあまり使わないからだろうなぁ
。
で、なんとなく思いついたので、ハッシュを作成するベンチマークを取ってみた。
何も考えずに書くとループして作るだろうなぁ、という感じのループと、そのループを展開したもの、そしてスライス代入と直接代入の4種類。
1
2
3
4
5
6
7
8
9
10
|
Benchmark: running Unroll, direct, for, slice for at least 3 CPU seconds...
Unroll: 2 wallclock secs ( 3.16 usr + 0.00 sys = 3.16 CPU) @ 264160.01/s (n=833689)
direct: 2 wallclock secs ( 3.15 usr + 0.00 sys = 3.15 CPU) @ 287373.38/s (n=906663)
for: 3 wallclock secs ( 3.13 usr + 0.00 sys = 3.13 CPU) @ 174892.19/s (n=546713)
slice: 3 wallclock secs ( 3.00 usr + 0.00 sys = 3.00 CPU) @ 282924.03/s (n=849055)
Rate for Unroll slice direct
for 174892/s -- -34% -38% -39%
Unroll 264160/s 51% -- -7% -8%
slice 282924/s 62% 7% -- -2%
direct 287373/s 64% 9% 2% --
|
ハッシュを直接書くよりはさすがに遅かったが、それにしても2%しか差がないのは驚き。
これは使わない手はないね。
で、ソースは以下のとおり。
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
|
use strict;
use warnings;
use Benchmark qw(:all);
our @la = (1 .. 5);
our @lb = ('one', 'two', 'three', 'four', 'five');
cmpthese(
timethese(
0, # 0 is auto
{
direct => sub {
my %hash = (
1 => 'one',
2 => 'two',
3 => 'three',
4 => 'four',
5 => 'five',
);
},
for => sub {
my %hash;
for my $i (0 .. 4) {
$hash{$la[$i]} = $lb[$i];
}
},
Unroll => sub {
my %hash;
$hash{$la[0]} = $lb[0];
$hash{$la[1]} = $lb[1];
$hash{$la[2]} = $lb[2];
$hash{$la[3]} = $lb[3];
$hash{$la[4]} = $lb[4];
},
slice => sub {
my %hash;
@hash{@la} = @lb;
},
}
)
);
|
Comments
comments powered by Disqus