Perl で時刻の文字列を生成する速い方法
DateTime が重くて遅いのは周知ですが、一応どれくらい差が出るかベンチマーク。
「2010-07-01 15:10:53」みたいなフォーマットのタイムスタンプ文字列を生成したい場合です。
DateTime はオブジェクトをキャッシュして使い回しても相当遅いです。
POSIX はコアモジュールで、Windows でも使えますので、使える環境では積極的に使いましょう。
他にももっと速い方法があれば、教えてください。
Benchmark: running dateime, dateime_c, posix for at least 3 CPU seconds... dateime: 3 wallclock secs ( 3.15 usr + 0.00 sys = 3.15 CPU) @ 2083.17/s (n=6562) dateime_c: 3 wallclock secs ( 3.47 usr + 0.00 sys = 3.47 CPU) @ 25739.19/s (n=89315) posix: 2 wallclock secs ( 1.99 usr + 1.10 sys = 3.09 CPU) @ 173061.81/s (n=534761) Rate dateime dateime_c posix dateime 2083/s -- -92% -99% dateime_c 25739/s 1136% -- -85% posix 173062/s 8208% 572% --
use strict; use warnings; use Benchmark ':all'; use DateTime; use POSIX; my $now = DateTime->now('time_zone' => 'UTC'); cmpthese(timethese( -3, { 'dateime' => \&datetime, 'dateime_c' => \&datetime_cache, 'posix' => \&posix, })); sub datetime { DateTime->now('time_zone' => 'UTC')->strftime('%Y-%m-%d %H:%M:%S'); } sub datetime_cache { $now->strftime('%Y-%m-%d %H:%M:%S'); } sub posix { POSIX::strftime '%Y-%m-%d %H:%M:%S', gmtime time; }
[追記]
id:sfujiwara 氏がコメントいただいた Time::Piece も加えてみました。
use Time::Piece (); sub piece_ymdhms { my $t = Time::Piece::gmtime time; $t->ymd . ' ' . $t->hms; } sub piece_strftime { my $t = Time::Piece::gmtime time; $t->strftime('%Y-%m-%d %H:%M:%S'); }
結果、今のところ POSIX 最速です。
Rate dateime dateime_c tp_ymd tp_strftime posix dateime 1536/s -- -91% -94% -95% -99% dateime_c 17269/s 1024% -- -30% -42% -86% tp_ymd 24653/s 1505% 43% -- -17% -80% tp_strftime 29531/s 1823% 71% 20% -- -77% posix 125962/s 8101% 629% 411% 327% --