Hateburo: kazeburo hatenablog

SRE / 運用系小姑 / Goを書くPerl Monger

Released POSIX::strftime::Compiler. GNU C library compatible strftime for loggers and servers

I released POSIX::strftime::Compiler v0.10 to CPAN.

https://metacpan.org/release/POSIX-strftime-Compiler
https://github.com/kazeburo/POSIX-strftime-Compiler

POSIX::strftime::Compiler provides GNU C library compatible strftime(3). But this module will not affected by the system locale. This feature is useful when you want to write loggers, servers and portable applications.

For generate same result strings on any locale, POSIX::strftime::Compiler wraps POSIX::strftime and converts some format characters to perl code

$ 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

And POSIX::strftime::Compiler reduce cost of setlocale.

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 result is

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%                --

POSIX::strftime::Compiler's strftime is faster than POSIX::strftime, because P::s::Compiler use sprintf() if all format characters are solved by easy calculation.

I have a plan to use this module in Apache::LogFormat::Compiler.