On Sat, November 22, 2008 12:50 am, Daisuke Maki wrote:
> So I have this requirement to make DateTime leaner, in terms of speed,
> load time, and the amount of memory consumed. The target is for casual
> users, so the use of XS code is not an option either.

In terms of speed, one of the things that's unique (AFAIK) to
DateTime is being able to thread-safely convert a datetime from
one timezone to another.

I'd be curious to know how it fares in this regard.  Here's a
benchmark that for me shows DateTime proper almost ten times as
slow as non-thread-safely using libc routines (suggestions for
improvement enthusiastically welcomed):

#!/usr/bin/perl -l

use strict;
use warnings;
use DateTime;
use Env::C;
use POSIX "mktime";

sub convert_timezone_datetime {
    my ($y,$mo,$d,$h,$m,$s,$tz,$new_tz) = @_;

    my $dt = DateTime->new(year=>$y, month=>$mo, day=>$d, hour=>$h,
minute=>$m, second=>$s,time_zone=>$tz);
    $dt->set_time_zone($new_tz);

    return map $dt->$_, qw/year month day hour minute second/;
}

sub convert_timezone_env_c {
    my ($y,$mo,$d,$h,$m,$s,$tz,$new_tz) = @_;
    my $save_tz = Env::C::getenv("TZ");

    Env::C::setenv("TZ",$tz,1);
    my $time = POSIX::mktime($s,$m,$h,$d,$mo-1,$y-1900,0,0,-1);

    Env::C::setenv("TZ",$new_tz,1);
    POSIX::tzset(); # localtime_r bug
    ($s,$m,$h,$d,$mo,$y) = localtime($time);
    $mo++; $y+=1900;

    # this belongs in a destructor
    if (defined $save_tz) { Env::C::setenv("TZ",$save_tz,1) }
    else { Env::C::unsetenv("TZ") }

    return ($y,$mo,$d,$h,$m,$s);
}

sub convert_timezone_system {
    my ($y,$mo,$d,$h,$m,$s,$tz,$new_tz) = @_;

    local $ENV{"TZ"} = $tz;
    my $time = POSIX::mktime($s,$m,$h,$d,$mo-1,$y-1900,0,0,-1);

    $ENV{"TZ"} = $new_tz;
    POSIX::tzset(); # localtime_r bug
    ($s,$m,$h,$d,$mo,$y) = localtime($time);
    $mo++; $y+=1900;

    return ($y,$mo,$d,$h,$m,$s);
}

print join ",",
datetime=>convert_timezone_datetime(2008,7,3,23,2,3,"America/Denver","America/New_York");
print join ",",
registry=>convert_timezone_env_c(2008,7,3,23,2,3,"America/Denver","America/New_York");
print join ",",
"system"=>convert_timezone_system(2008,7,3,23,2,3,"America/Denver","America/New_York");

use Benchmark "timethese";
timethese(-5, {
    datetime => sub { my ($y,$mo,$d,$h,$m,$s) =
convert_timezone_datetime(2008,7,3,23,2,3,"America/Denver","America/New_York");
return },
    env_c => sub { my ($y,$mo,$d,$h,$m,$s) =
convert_timezone_env_c(2008,7,3,23,2,3,"America/Denver","America/New_York");
return },
    "system" => sub { my ($y,$mo,$d,$h,$m,$s) =
convert_timezone_system(2008,7,3,23,2,3,"America/Denver","America/New_York");
return },
} );


Reply via email to