Practice of Programming

プログラム とか Linuxとかの話題

ループ回数が多いときにDateTime使うのはやめよう

ボトルネックを探していたら、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