On 7/5/05, Rick Measham <[EMAIL PROTECTED]> wrote:
> DateTime::Diet (attached) is a simple wrapper around DateTime that
> handles simple new(), set() and get methods. If you ask it for something
> it can't handle by itself, it reblesses your object into full DateTime
> and then calls the method on the DateTime object.

If you're going for speed, there's more low-hanging fruit to be had.  Check
out my modifications in DateTime::Diet2 (attached).

---

These tests compare DateTime::Diet[2] to DateTime for object creation, plus
simple accessors and mutators

                   Rate        DateTime  DateTime::Diet DateTime::Diet2
       DateTime  1754/s              --            -94%            -98%
 DateTime::Diet 28736/s           1538%              --            -66%
DateTime::Diet2 84746/s           4731%            195%              --


These tests compare DateTime::Diet[2] to DateTime for the same things, but
then call a non-diet function causing the object to become a full blown
DateTime object.

                  Rate        DateTime  DateTime::Diet DateTime::Diet2
       DateTime 1629/s              --            -47%            -53%
 DateTime::Diet 3049/s             87%              --            -11%
DateTime::Diet2 3436/s            111%             13%              --

---

I'll bet you could get another few percent by using string eval to generate
the accessor methods...

-John

package DateTime::Diet;

use strict;
use warnings;

use DateTime;
use vars qw/$AUTOLOAD/;

sub new {
    my $class = shift;
    my %args = @_;

    return bless \%args, $class;
}

sub AUTOLOAD {

    my $attr = $AUTOLOAD;
    $attr =~ s/.*:://;
    return unless $attr =~ /[^A-Z]/;  # skip DESTROY and all-cap methods

    if ($attr && 
$attr=~/^set_(year|month|hour|minute|second|nanosecond|locale|time_zone)$/) {
        $_[0]->{$1} = $_[1];
        return $_[0];
    }
    if ($attr && $attr=~/^(month|day|hour|min(ute)?|sec(ond)?)$/) {
        return $_[0]->{$1} if $_[0]->{$1};
        return 1 if $1=~/month|day/;
        return 0;
    }

    $_[0] = bless \%{new DateTime(%{$_[0]})}, 'DateTime';
    return $_[0]->$attr(@_);
}

package DateTime::Diet2;

use strict;
use warnings;

use DateTime;
our $AUTOLOAD;

sub new
{
  my $class = shift;
  return bless { @_ }, $class;
}

sub DESTROY { }

BEGIN
{
  no strict 'refs';

  foreach my $attr (qw(year month hour minute second nanosecond locale 
time_zone))
  {
    my $method = "set_$attr";
    *$method = sub { $_[0]->{$attr} = $_[1]; return $_[0] };
  }

  foreach my $method (qw(month day))
  {
    *$method = sub 
    {
      return $_[0]->{$method}  if($_[0]->{$method});
      return 1;
    }
  }

  foreach my $method (qw(hour minute second))
  {
    *$method = sub 
    {
      return $_[0]->{$method}  if($_[0]->{$method});
      return 0;
    }
  }

  *min = \&minute;
  *sec = \&second;
}

sub AUTOLOAD
{
  my $attr = $AUTOLOAD;
  $attr =~ s/.*:://;
  $_[0] = bless \%{new DateTime(%{$_[0]})}, 'DateTime';
  return $_[0]->$attr(@_);
}

package main;

use DateTime;
use Benchmark q(cmpthese);

print "These tests compare DateTime::Diet[2] to DateTime for object creation, 
plus simple accessors and mutators\n\n";
cmpthese(50000, {
    '       DateTime' => sub { my $dt = new DateTime( year => 2004 ); my $day = 
$dt->day; $dt->set_minute(22); },
    ' DateTime::Diet' => sub { my $dt = new DateTime::Diet( year => 2004 ); my 
$day = $dt->day; $dt->set_minute(22); },
    'DateTime::Diet2' => sub { my $dt = new DateTime::Diet2( year => 2004 ); my 
$day = $dt->day; $dt->set_minute(22); },
});

print "\n\nThese tests compare DateTime::Diet[2] to DateTime for the same 
things, but then call a non-diet function causing the object to become a full 
blown DateTime object.\n\n";
cmpthese(10000, {
    '       DateTime' => sub { my $dt = new DateTime( year => 2004 ); my $day = 
$dt->day; $dt->set_minute(22); $dt->datetime; $day=$dt->day; },
    ' DateTime::Diet' => sub { my $dt = new DateTime::Diet( year => 2004 ); my 
$day = $dt->day; $dt->set_minute(22); $dt->datetime; $day=$dt->day; },
    'DateTime::Diet2' => sub { my $dt = new DateTime::Diet2( year => 2004 ); my 
$day = $dt->day; $dt->set_minute(22); $dt->datetime; $day=$dt->day; },
});

Reply via email to