ボトルネックを探していたら、5000回くらいのループでDateTimeを使っている場面だったという話。
簡単な例として、1分追加する処理でベンチマークとってみた。
Benchmark: running datetime, timepiece for at least 3 CPU seconds... datetime: 3 wallclock secs ( 3.14 usr + 0.00 sys = 3.14 CPU) @ 2720.70/s (n=8543) timepiece: 4 wallclock secs ( 2.70 usr + 0.55 sys = 3.25 CPU) @ 60119.38/s (n=195388)
5000回のループだったら、DateTimeが1.8秒かかるのに対して、Time::Pieceなら、0.01秒弱。
ベンチマークのコードは下記。
#!/usr/bin/perl use strict; use warnings; use DateTime; use Time::Piece (); use Benchmark qw/cmpthese timethese/; my $time = time; my $dt = DateTime->now(epoch => $time); my $tp = Time::Piece::localtime($time); timethese(0, {datetime => sub { $dt->add(minutes => 1); }, timepiece => sub { $tp += 60; }}, );
実際のコードでは、ループが大きいのはなくせないんだけど、日付の演算を毎回使う必要はなかったので、使う数はだいぶ数は減ったんですけども。
そもそも、epoch time で記録すべきだったとか、今更感漂う今日この頃に orz