POSIXのstrftimeが生perlcodeよりも速い件について

しばらく前に、POSIXにstrftimeという便利なコマンドがあるのを発見した。 DateTime等とのベンチマークだったと思う。 はてブしたハズなのだが、見つからず。 タグのつけ方が安定しない…。 ともかく。 日付時刻を表示するときは、localtimeをスカラーコンテキストで表示することが多いのだが、日本風に表示しようとすると、それなりに面倒。

1
2
3
4
my @now = localtime;
$now[5] += 1900;
$now[4]++;
printf qq{%04d/%02d/%02d %02d:%02d:%02d}, reverse(@now[0..5]);

そこで便利なのが、POSIXのstrftimeですよ。

1
2
use POSIX;
print POSIX::strftime '%Y/%m/%d %H:%M:%S', localtime;

これで同じ出力を得ることが出来る。 しかも、手元の環境では、strftimeを使ったほうが速い。

生のコードは2種類。 先ほどのスライスを使ったものと、配列を展開したもの。 それらとstrftimeを比較してみた。 結果は以下のとおり、POSIXを使ったほうが2割程度速かった。

1
2
3
4
5
6
7
8
Benchmark: running coding1, coding2, posix for at least 3 CPU seconds...
coding1:  4 wallclock secs ( 3.10 usr +  0.00 sys =  3.10 CPU) @ 75042.20/s (n=232931)
coding2:  4 wallclock secs ( 3.15 usr +  0.00 sys =  3.15 CPU) @ 84113.30/s (n=265041)
posix:  4 wallclock secs ( 3.14 usr +  0.00 sys =  3.14 CPU) @ 103140.63/s (n=323449)
Rate coding1 coding2   posix
coding1  75042/s      --    -11%    -27%
coding2  84113/s     12%      --    -18%
posix   103141/s     37%     23%      --

ソースコードも見た目にわかりやすいので、今後は重宝しそうです。 ベンチマークに使ったソースは以下のとおり。

 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
#utf8
use strict;
use warnings;
use utf8;
use Benchmark ':all';
use POSIX;
use Perl6::Say;
say posix();
say coding();
say coding2();
cmpthese(timethese( -3, {
'posix'   => \&posix,
'coding1' => \&coding,
'coding2' => \&coding2,
}));
sub posix {
POSIX::strftime '%Y/%m/%d %H:%M:%S', localtime;
}
sub coding {
my @now = localtime;
$now[5] += 1900;
$now[4]++;
sprintf qq{%04d/%02d/%02d %02d:%02d:%02d}, reverse(@now[0..5]);
}
sub coding2 {
my @now = localtime;
sprintf qq{%04d/%02d/%02d %02d:%02d:%02d},
$now[5] + 1900, $now[4] + 1, $now[3], $now[2], $now[1], $now[0];
}

Comments

comments powered by Disqus