1週間ぐらいtrialでしたが、Windowsでも動いたようなので0.10を出しました。すごーーーく、、、、ニッチです
https://metacpan.org/release/POSIX-strftime-Compiler
https://github.com/kazeburo/POSIX-strftime-Compiler
POSIX::strftime::CompilerはGNU互換で、ロケールの設定に影響を受けないstrftime(3)を提供します。WindowsでもGNU互換の文字が使えます。おそらくloggerとかloggerとかloggerに便利です
$ LC_ALL=ja_JP.UTF-8 perl -Ilib -MPOSIX::strftime::Compiler -E '
say POSIX::strftime::Compiler::strftime(q!%d/%b/%Y:%T %z!,localtime);
say POSIX::strftime(q!%d/%b/%Y:%T %z!,localtime)
'
21/Jan/2014:10:48:12 +0900
21/ 1月/2014:10:48:12 +0900
POSIX::strftime::CompilerのstrftimeはPOSIX::strftimeをwrapし、ロケールに影響をうけるフォーマット文字の部分を先に入れ替えています。
Apache::LogFormat::Compilerではstrftimeの前後にsetlocale(3)をしていますが、POSIX::strftime::Compilerを使えばそのコストを減らす事が出来ます。
use Benchmark qw/:all/;
use POSIX qw//;
use POSIX::strftime::Compiler;
my $fmt = '%d/%b/%Y:%T';
cmpthese(timethese(-1, {
'compiler_function' => sub {
POSIX::strftime::Compiler::strftime($fmt, localtime($t));
},
'posix_and_locale' => sub {
my $old_locale = POSIX::setlocale(&POSIX::LC_ALL);
POSIX::setlocale(&POSIX::LC_ALL, 'C');
POSIX::strftime($fmt,localtime($t));
POSIX::setlocale(&POSIX::LC_ALL, $old_locale);
},
'posix' => sub {
POSIX::strftime($fmt,localtime($t));
},
}));
ベンチマーク結果
Benchmark: running compiler_function, posix, posix_and_locale for at least 1 CPU seconds...
compiler_function: 1 wallclock secs ( 1.10 usr + 0.00 sys = 1.10 CPU) @ 446836.36/s (n=491520)
posix: 1 wallclock secs ( 1.01 usr + 0.00 sys = 1.01 CPU) @ 243326.73/s (n=245760)
posix_and_locale: 1 wallclock secs ( 1.10 usr + 0.00 sys = 1.10 CPU) @ 71087.27/s (n=78196)
Rate posix_and_locale posix compiler_function
posix_and_locale 71087/s -- -71% -84%
posix 243327/s 242% -- -46%
compiler_function 446836/s 529% 84% --
setlocaleする場合より6倍程度良い数値がでています。また、POSIX::strftimeの倍程度の速度がでています。これは全てのフォーマット文字が複雑な計算などをする必要が無い文字の場合にsprintfだけで結果を出してしまう為です。
Apache::LogFormat::Compilerで使おうかなと考えて作ったのですが、'%z'の計算が速くならないのであまり嬉しい事がなかったという今現在なう