ゆるゆる〜tech ver〜

勉強したこととかかく

mapっぽくなにか

先日気になったのでどうなのかなーって思って調べた話。(for Perl)

my @array = ( 1..1_000 );

この配列の値をハッシュのkeyにして扱いやすくしてあれこれしていく、っていうを割とやるのですが、 だいたい

my %map = map { $_ => 1 } @array;

とか

my %map;
foreach my $id ( @array ) {
    $map{$id} = 1;
}

とかってやってたのですが先日

my %map;
@map{@array} = ();

outout が \%map = { 1 => undef, 2 => undef, .... } こう書いた方が速いです、というコメントを見て、こんな書き方できるのかーって思ったのと 本当に速いんですか?って思ったので調べた。

#!/usr/bin/env perl
use strict;
use warnings;
use Time::HiRes qw(gettimeofday tv_interval);
my @array = ( 1..1_000 );
{
    my $t0 = [gettimeofday];
    my %map;
    @map{@array} = ();
    my $elapsed = tv_interval($t0);
    print '--@map{@array}--' . "\n";
    print $elapsed * 1000 . "\n";
}
{
    my $t0 = [gettimeofday];
    my %map = map { $_ => 1 } @array;
    my $elapsed = tv_interval($t0);
    print '--map--' . "\n";
    print $elapsed * 1000 . "\n";
}
{
    my $t0 = [gettimeofday];
    my %map;
    foreach my $id ( @array ) {
        $map{$id} = 1;
    }
    my $elapsed = tv_interval($t0);
    print '--foreach--' . "\n";
    print $elapsed * 1000 . "\n";
}
{
    my $t0 = [gettimeofday];
    my %map;
    for my $id ( @array ) {
        $map{$id} = 1;
    }
    my $elapsed = tv_interval($t0);
    print '--for--' . "\n";
    print $elapsed * 1000 . "\n";
}

1;

実行結果

1_000_000で実行

$perl sample.pl
--@map{@array}--
740.508
--map--
1199.097
--foreach--
639.542
--for--
650.275

10_000_000 で実行

$perl sample.pl 10_000_000
--@map{@array}--
11308.191
--map--
16796.802
--foreach--
9985.983
--for--
10101.491

※ foreachとforが定期的にどっちが速いのかわからなくなるのでまた調べた。 一応 perlsyn - perldoc.perl.org

The foreach keyword is actually a synonym for the for keyword, so you can use either

for と foreachはperldocで同義ですよって言われている。 foreachが速いって思ってたんだけどPHPとごっちゃになってるのかな。

[PHP]ループのメモリ使用量と処理速度を比較しました - Qiita

とにかく

foreach = for > @map{@array} > map

の順で速かったので mapより @map{@array} にしたほうが速かった。

ちなみに valueがundefになって速いなら

my %map;
foreach my $id ( @array ) {
    $map{$id} = undef;
}

にしたら速くなるのでは?と思ったけどそんなことはなかった。

まあけど、可読性がよくなるという理由以外にmap使わないようにしましょうって話ですね。

ワンライナーかっこいいという理由でmap使いがちでした/(^o^)\おわた