Time::Moment 可节省时间

很久以前,在一个遥远的星系中,叛军联盟遇到了一个小问题,因为载着公主的飞船因软件处于错误时区而晚出发了两小时,遇到了提前一小时巡逻的帝国巡洋舰。坏人们在移除那个特殊案例时无意中解决了叛军的问题,移除了错误的时区——这是一个程序员熟悉的解决方案。叛军在他们的防御留下一个实体的洞时,无意中利用了帝国的漏洞。
你可能认为我们现在正处于计算机革命之中(Alan Kay 说我们不是),但我们拥有所有这些华丽的硬件,廉价的或免费的平台和服务,以及我们拥有的惊人的编程工具,我们处理时间和日期的方式通常是一团糟。Y2K 远不及这个。
当 Dave Rolsky 推出 DateTime 时,每个人都欣喜若狂。这是一件杰作般的软件,力求在纳秒和闰秒上做到一丝不苟。在此之前,我使用了一堆模块来处理日期,并避免使用日期数学。
DateTime 可以表示日期,并告诉我关于它们的各种信息,例如季度中的某一天,提供特定地区的名称,以有趣的方式格式化,还可以告诉我日期之间的差异。
use Date::Time;
my $dt = DateTime->new(
year => 2014,
month => 12,
day => 18,
hour => 12,
minute => 37,
second => 57,
nanosecond => 0,
time_zone => 'UTC',
);
my $quarter = $dt->quarter;
my $day_of_quarter = $dt->day_of_quarter;
my $month_name = $dt->month_name; # can be locale specific
my $ymd = $dt->ymd('/'); # 2015/02/06
my $now = DateTime->now;
my $duration = $now - $dt;
DateTime 不解析日期。同一命名空间中的其他模块可以做到这一点,同时返回一个 DateTime 对象。例如,DateTime::Format::W3CDTF 模块解析日期并将它们转换为对象。
use DateTime::Format::W3CDTF;
my $w3c = DateTime::Format::W3CDTF->new;
my $dt = $w3c->parse_datetime( '2003-02-15T13:50:05-05:00' );
# 2003-02-15T13:50:05-05:00
$w3c->format_datetime($dt);
太棒了。 DateTime 是任何日期问题的标准答案。它几乎不需要我思考就能工作。
但 DateTime 有一个问题。它创建了大对象,在兴奋地使用一些可以工作的东西(慢而正确比快而错误要好)时,我可能会最终拥有数百个这样的对象,没有留下太多空间给其他东西。尝试将其中一个对象转储以查看其范围。我不会在这篇文章中浪费空间。
尽管 DateTime 非常精确,有时我希望能稍微不那么精确,并且要快得多。这就是 Christian Hansen 的 Time::Moment 的作用(参见他的 Time::Moment vs DateTime)。它使用 UTC,忽略闰秒,并将日期限制在公元1年至9999年之间。它的对象是不可变的,因此它可以稍微快一点。要获取新的日期时间,您会得到一个新的对象。它还具有许多常见功能和接近 DateTime 的接口。
Time::Moment 发行版附带一个程序 dev/bench.pl,它允许我比较性能。以下是一些输出结果
$ perl dev/bench.pl
Benchmarking constructor: ->new()
Rate DateTime Time::Moment
DateTime 14436/s -- -99%
Time::Moment 1064751/s 7276% --
让我们做一个更有趣的基准,从一个字符串中构造一个对象,向它添加一天,并检查它是否在今天之前。像每个基准一样,您必须根据您的特定用途进行检查
use Benchmark;
use DateTime;
use Time::Moment;
use DateTime::Format::W3CDTF;
my $dtf_string ='2014-02-01T13:01:37-05:00';
my $time_moment = sub {
my $tm = Time::Moment->from_string( $dtf_string );
my $tm2 = $tm->plus_days( 1 );
my $now = Time::Moment->now;
my $comparison = $now > $tm2;
};
my $datetime = sub {
my $w3c = DateTime::Format::W3CDTF->new;
my $dt = $w3c->parse_datetime( $dtf_string );
$dt->add( days => 1 );
my $now = DateTime->now;
my $comparison = $now > $dt;
};
Benchmark::cmpthese( -10, {
'Time::Moment' => $time_moment,
'DateTime' => $datetime,
});
Time::Moment 仍然非常快。令人惊讶地快
$ perl dtf_bench.pl
Rate DateTime Time::Moment
DateTime 1889/s -- -99%
Time::Moment 273557/s 14384% --
如果我的问题在 Time::Moment 的限制内(谁会需要超过640k?),我可以获得巨大的收益。当这不再适用时,我可以通过一点工作切换到 DateTime。无论如何,你可能想要擦除你的机器人的记忆。
本文最初发布在 PerlTricks.com。
标签
反馈
这篇文章有什么问题吗?请在GitHub上打开一个issue或pull request来帮助我们,链接为:GitHub
- More commenting... maybe?
github.polettix.it - Perl Weekly Challenge 121: Invert Bit
blogs.perl.org - Web nostalgia: MojoX::Mechanize
github.polettix.it - On the eve of CPAN Testers
blogs.perl.org - PWC121 - The Travelling Salesman
github.polettix.it - PWC121 - Invert Bit
github.polettix.it - Floyd-Warshall algorithm implementations
github.polettix.it - Perl Weekly Challenge 120: Swap Odd/Even Bits and Clock Angle
blogs.perl.org - How I Uploaded a CPAN Module
blogs.perl.org - App::Easer released on CPAN
github.polettix.it