UNIXコマンド呼び出しと組み込み関数のベンチマーク

Perlベンチマークスクリプトを書いた事がなかったので、試しに書いてみました。

シェルのlsコマンドを呼ぶ場合と、opendirしてループでreaddirする場合(=Perl組み込みのサブルーチンのみを使用)との性能比較です。

#!/usr/bin/perl
use strict;
use warnings;
use Benchmark;

my $count = 10000;

timethese ( $count,
            { 'UNIX COMMAND', '&by_unix_command;',
              'PERL SUBROUTINE', '&by_perl_subroutine;' } );

sub by_unix_command {
    chomp ( my @file_list = `ls *.txt` );   
    \@file_list;
}

sub by_perl_subroutine {
    my @file_list;
    opendir DIR, ".";
    while ( defined ( my $file = readdir DIR ) ) {
        push @file_list, $file
            if ! -d $file and $file =~ m/.txt$/;
    }
    closedir DIR;
    \@file_list;
}

結果の違いは歴然ですね。*1

Benchmark: timing 10000 iterations of PERL SUBROUTINE, UNIX COMMAND...
PERL SUBROUTINE:  1 wallclock secs ( 0.56 usr + 0.33 sys = 0.88 CPU) @ 11327.43/s (n=10000)
UNIX COMMAND: 49 wallclock secs ( 0.72 usr + 3.06 sys + 15.72 cusr 28.91 csys = 48.40 CPU ) @ 2645.31/s (n=10000)

*1:2ヶ月くらい前に「UNIXコマンド呼んで得た結果にchompするの忘れがちだよね」だとか書いてました。他のコマンドならまだしもlsコマンドで。消したい過去・・