2014/05/26(月)Perl Data Language 基礎編 #05 「PDLとPerlの変数間のやりとり、null、バッド値の伝染、PDL生成のベンチマーク」

まだデータフローの説明、グラフ描画の説明もあるので#10ぐらいまで統計に入れないかも。

#!/usr/bin/env perl

use strict;
use warnings;
use feature qw/say/;
use PDL;
use DDP filters => { -external => [ 'PDL' ] };

my $a = pdl [ [1,2,3], [4,5,6] ];
say $a;
print "\n";

say "PDL から Perl のリストに変換:";
my @b = $a->list;
say @b;
print "\n";

say "PDL から Perl のスカラーに変換(at(4)):";
say PDL->new([8,7,3,9,1,6,8])->at(4);
print "\n";

say "Perl のリストから PDL へ:";
my $c = pdl @b;
say $c;
print "\n";

say "PDL の null";
# どんな次元にも拡張するプレースホルダー
# ライトバック戻り値として関数に渡す場合に有効
# たぶん破壊的な関数を作るような場合のこと
my $null = PDL->null;
say p $null;
say "ピドルはnullです" if $null->isnull;
say "ピドルは空です"   if $null->isempty;
print "\n";

say "バッド値を伝染させる:";
# バッド値に関しては、#02を参照
my $hasbad = pdl 'bad';
my $d = PDL->null;
say "hasbad にバッド値あり" if $hasbad->badflag;
say "d      にバッド値なし" unless $d->badflag;
say '$d = $hasbad + 3';
$d = $hasbad + 3;
say "d      にバッド値あり" if $d->badflag;

実行結果↓

[
 [1 2 3]
 [4 5 6]
]


PDL から Perl のリストに変換:
123456

PDL から Perl のスカラーに変換(at(4)):
1

Perl のリストから PDL へ:
[1 2 3 4 5 6]

PDL の null
PDL {
    Data     : Null
    Type     : unsigned char
    Shape    : [0]
    Nelem    : 0
    Min      : 0
    Max      : 0
    Badflag  : No
    Has Bads : No
}
ピドルはnullです
ピドルは空です

バッド値を伝染させる:
hasbad にバッド値あり
d      にバッド値なし
$d = $hasbad + 3
d      にバッド値あり

PDLの生成で普通の配列で渡すか配列のリファレンスで渡すかでスピードが変わるか気になったのでPDL生成のベンチマークをとりました。配列のリファレンスで渡したほうがやや速いですな。

#!/usr/bin/env perl

use strict;
use warnings;
use Benchmark;
use PDL;

my @array = 1 .. 10;

Benchmark::cmpthese(-1, {
    '@array'    => sub { pdl @array  },
    '\@array'   => sub { pdl \@array },
});

ベンチマークの結果↓

           Rate  @array \@array
@array  43115/s      --    -21%
\@array 54613/s     27%      --