sub xxxx { ... my @tmp_xxxx = split(" ", <FH>) ; return $tmp_xxxx[38] ; }これを見ていたら、@tmp_xxxx が無駄に思えてきました。オブジェクト指向言語っぽく、split(" ", <FH>)[38] のように書けないのか?と思ったわけです。
調べてみると、無名配列を使うと、次のように書けることを知りました。
sub xxxx { ... return = [split(" ", <FH>)]->[38] ; }これいいなと思って、他の似た箇所も全部これのほうが良いかなと、さらに自作スクリプトを眺めてみたら、次のようなコードもありました。
... (undef, $p) = split(" ", $k) ...これを見て、性能面では、どの書き方が良いのか?ということが気になってしまいました。
そこで、ベンチマークで確認しました。
#use strict; #use warnings; use Benchmark qw(cmpthese timethese :hireswallclock); $x = "a b c d e f g h i j k l m n o p" ; cmpthese(1000000,{ method1 => sub { (undef,undef,undef,undef,undef,undef,undef,undef,undef,undef,undef,undef,undef,undef,undef, my $y) = split(" ", $x) ; }, method2 => sub { my $y = [split(" ", $x)]->[15] ; }, method3 => sub { my @temp = split(" ", $x) ; my $y = $temp[15] ; }, });
[root@hoge ]# cat /etc/redhat-release CentOS Linux release 7.2.1511 (Core) [root@hoge ]# rpm -q perl perl-5.16.3-286.el7.x86_64 [root@hoge ]# perl bench_split16.pl Rate method2 method3 method1 method2 386100/s -- -11% -43% method3 434783/s 13% -- -36% method1 680272/s 76% 56% --このように、無名配列(method2)が一番遅いという結果になりました。しかしながら、[38] などという場合は、実行頻度も加味して、可読性の観点から、無名配列による書き方を選んだほうが良い場合もあると思います。
なお、興味深いことに、CentOS 6 では順序が入れ替わります。
[root@hoge ~]# cat /etc/redhat-release CentOS release 6.7 (Final) [root@hoge ~]# rpm -q perl perl-5.10.1-141.el6.x86_64 [root@hoge ~]# perl bench_split16.pl Rate method3 method2 method1 method3 349650/s -- -19% -48% method2 432900/s 24% -- -35% method1 671141/s 92% 55% --ThinkPad W520 のマルチブート環境にて実行しています。
perl を毛嫌いする人を見かけますが、この記事に書いたような側面(同じことを幾通りにも書ける)からなのだろうか?と思いました。ところが、これこそ perl の面白さと思うのです。私的には。
よーし、今こそ、もっと perl 勉強しよう (活用しよう) っと!
2016-04-14追記
「Effective Perl」を読んでみたら、スライスを使って次のように書けることを知りました。
method4 => sub { my ($y) = (split(" ", $x))[15] ; },ふたたび、ベンチマークしてみると、スライス(method4)が1番速いという結果になりました。
[root@hoge ~]# cat /etc/redhat-release CentOS release 6.7 (Final) [root@hoge ~]# rpm -q perl perl-5.10.1-141.el6_7.1.x86_64 [root@hoge ~]# perl bench_split16.pl Rate method3 method2 method1 method4 method3 255754/s -- -17% -46% -48% method2 307692/s 20% -- -34% -38% method1 469484/s 84% 53% -- -5% method4 495050/s 94% 61% 5% -- [root@hoge ~]# service cpuspeed start Enabling ondemand cpu frequency scaling: [ OK ] [root@hoge ~]# perl bench_split16.pl Rate method3 method2 method1 method4 method3 347222/s -- -19% -46% -49% method2 431034/s 24% -- -33% -36% method1 645161/s 86% 50% -- -5% method4 675676/s 95% 57% 5% --本題からそれますが、cpuspeed を止めていると Turbo Boost まで効かなくなるようで、パフォーマンス低下するようです。前回のベンチの際は、chkconfig on にしてたんですが、性能下がるかと思って off にしてましたが、逆効果でした。マシンは、ThinkPad W520 (Core i7 2960XM) です。利用シーンによっては、逆手にとって、静音性のために chkconfig cpuspeed off もよいかもしれません。
0 件のコメント:
コメントを投稿