note
hdb
<p>
Another small speed up can be achieved by replacing
</p>
<code>
my $leaps = int( ($y - 1970) / 4 + 0.5 );
(((($y-1970)*365 +$leaps+MONTHS->{$m}+($d-1))*24 +$H)*60 +$M)*60 +$S;
</code>
<p>with</p>
<c>
(((int(($y-1970)*365.25-.5)+MONTHS->{$m}+$d)*24 +$H)*60 +$M)*60 +$S;
</c>
<p>
in my experiments between 5 to 10%. All other attempts using split and unpack are much slower. I found <c>substr</c> to be very fast:
</p>
<c>
sub str2epoch3 {
(((int((substr($_[0],12,4)-1970)*365.25-.5)+
MONTHS->{substr($_[0],8,3)}+substr($_[0],5,2))*24 +substr($_[0],17,2))*60 +
substr($_[0],20,2))*60 +substr($_[0],23,2);
}
</c>
<p>
about 60% faster than [BrowserUk]'s code. I wonder whether there is something wrong...
</p>
Here is my full code:
<readmore>
<code>
use strict;
use warnings;
use Benchmark qw/cmpthese/;
use constant MONTHS => { qw[
Jan 0 Feb 31 Mar 59 Apr 90 May 120 Jun 151
Jul 181 Aug 212 Sep 242 Oct 272 Nov 303 Dec 334
] };
sub str2epoch {
my( $d, $m, $y, $H, $M, $S ) = $_[0] =~
m[^.... (\d\d) (...) (\d\d\d\d) (\d\d):(\d\d):(\d\d)]
or die "Bad format $_[0]";
my $leaps = int( ($y - 1970) / 4 + 0.5 );
(((($y-1970)*365 +$leaps+MONTHS->{$m}+($d-1))*24 +$H)*60 +$M)*60 +$S;
}
sub str2epoch2 {
my( $d, $m, $y, $H, $M, $S ) = $_[0] =~
m[^.... (\d\d) (...) (\d\d\d\d) (\d\d):(\d\d):(\d\d)]
or die "Bad format $_[0]";
(((int(($y-1970)*365.25-.5)+MONTHS->{$m}+$d)*24 +$H)*60 +$M)*60 +$S;
}
sub str2epoch3 {
(((int((substr($_[0],12,4)-1970)*365.25-.5)+
MONTHS->{substr($_[0],8,3)}+substr($_[0],5,2))*24 +substr($_[0],17,2))*60 +
substr($_[0],20,2))*60 +substr($_[0],23,2);
}
my $str = 'Fri, 01 Mar 2013 01:21:14 +0000';
cmpthese( -3, {BrowserUK => sub { str2epoch ($str) },
BUK2 => sub { str2epoch2($str) },
substr => sub { str2epoch3($str) }, }
);
</readmore>
</code>
1043832
1043841