Re: DateTime.pm on a Diet
Dave Rolsky wrote: DateTime::Shim DateTime::Trampoline DateTime::ThinShim DateTime::Proxy DateTime::Diet - not awful but a little cute, methinks ;) Of the above, I still like DT:Diet. If you want something less cute/more serious how about: DateTime::FastConstructor The others listed above don't seems to convey the purpose of the module. Cheers! Rick Measham
Re: DateTime.pm on a Diet
On Wed, 6 Jul 2005, John Peacock wrote: At the risk of sounding flippant, why not rename the existing DateTime class to DateTime::Fat (or the less inflamatory DateTime::Base) and put the proposed module in it's place as DateTime. If it is designed well, everything should Just Work(TM) with the shim class, which should always be faster than the existing class, even with the extra dispatch to plump up the object when needed. At first I thought this might be a good idea .. Dave Rolsky wrote: It has a pretty different API, in that it's new() constructor accepts anything without validation. I suppose it could check for extra args and call DateTime::Fat->new() if needed. I think that'd be a possibility, but it'd have to pass the DateTime.pm test suite in that case. We'd need to bring complete validation back in though. Otherwise your object dies unexpectedly later on: $dt = DateTime::Diet->new( year => 2004, month => 232 ); print $dt->year; #2004 print $dt->month; #232 print $dt->monthname; # DIE: Illegal value passed to DateTime::new This needs to be an *alternate* rather than standard way of creating DateTime objects, and the documentation will basically just tell you that you need to be very aware of the lack of immediate validation. Cheers! Rick Measham
Re: DateTime.pm on a Diet
On Wed, 6 Jul 2005, John Peacock wrote: At the risk of sounding flippant, why not rename the existing DateTime class to DateTime::Fat (or the less inflamatory DateTime::Base) and put the proposed module in it's place as DateTime. If it is designed well, everything should Just Work(TM) with the shim class, which should always be faster than the existing class, even with the extra dispatch to plump up the object when needed. It has a pretty different API, in that it's new() constructor accepts anything without validation. I suppose it could check for extra args and call DateTime::Fat->new() if needed. I think that'd be a possibility, but it'd have to pass the DateTime.pm test suite in that case. -dave /*=== VegGuide.Orgwww.BookIRead.com Your guide to all that's veg. My book blog ===*/
Re: DateTime.pm on a Diet
Dave Rolsky wrote: It sounded like people were interested. And maybe it's a "if you build it they will come" thing ;) Anyway, go for it and let's brainstorm on a better namespace. Here's some thoughts: At the risk of sounding flippant, why not rename the existing DateTime class to DateTime::Fat (or the less inflamatory DateTime::Base) and put the proposed module in it's place as DateTime. If it is designed well, everything should Just Work(TM) with the shim class, which should always be faster than the existing class, even with the extra dispatch to plump up the object when needed. John -- John Peacock Director of Information Research and Technology Rowman & Littlefield Publishing Group 4720 Boston Way Lanham, MD 20706 301-459-3366 x.5010 fax 301-429-5747
Re: DateTime.pm on a Diet
On Thu, 7 Jul 2005, Rick Measham wrote: So .. would this module actually get used by anyone but me? If so I'll go ahead and polish it off. It sounded like people were interested. And maybe it's a "if you build it they will come" thing ;) Anyway, go for it and let's brainstorm on a better namespace. Here's some thoughts: DateTime::Shim DateTime::Trampoline DateTime::ThinShim DateTime::Proxy DateTime::Diet - not awful but a little cute, methinks ;) -dave /*=== VegGuide.Orgwww.BookIRead.com Your guide to all that's veg. My book blog ===*/
Re: DateTime.pm on a Diet
On Wed, 6 Jul 2005, John Siracusa wrote: If you're going for speed, there's more low-hanging fruit to be had. Check out my modifications in DateTime::Diet2 (attached). Dave Rolsky wrote: Yeah, I was thinking that we'd do something like this if we're going to turn this into an officially blessed implementation. I was assuming Rick just used AUTOLOAD for a quick proof of concept. I was .. however, as Dave later suggests, I'd planned on actually creating the subs as perl subs .. not even having the overhead of the autocreation in BEGIN. .. sub minute { return $_[0]->{minute} || 0 } .. So .. would this module actually get used by anyone but me? If so I'll go ahead and polish it off. Cheers! Rick Measham
Re: Set::Infinite and DateTime::Set for Perl 6
On Wed, 6 Jul 2005, Flavio S. Glock wrote: This is the beginning of the Set::Infinite and DateTime::Set packages for Perl 6. There is not much written yet. Set::Infinite will probably be split in 3 classes, mirroring the DateTime::Set package structure: - Set::Span / DateTime::Span - a single span - Set::Recurrence / DateTime::Set - recurrences, ordered sets - Set::Infinite / DateTime::SpanSet - everything else - span recurrences, multiple spans You should get a commit bit from autrijus for Pugs. One thing I saw right off. You don't need to write accessors for attributes. Any attribute declared as ".foo" (. instead of :) is publically readable and looks like a method outside the class scope. -dave /*=== VegGuide.Orgwww.BookIRead.com Your guide to all that's veg. My book blog ===*/
Set::Infinite and DateTime::Set for Perl 6
This is the beginning of the Set::Infinite and DateTime::Set packages for Perl 6. There is not much written yet. Set::Infinite will probably be split in 3 classes, mirroring the DateTime::Set package structure: - Set::Span / DateTime::Span - a single span - Set::Recurrence / DateTime::Set - recurrences, ordered sets - Set::Infinite / DateTime::SpanSet - everything else - span recurrences, multiple spans Flavio S. Glock Set-Infinite-0.01.tar.gz Description: GNU Zip compressed data DateTime-Set-0.01.tar.gz Description: GNU Zip compressed data
Re: DateTime.pm on a Diet
On Wed, 6 Jul 2005, Eric Cholet wrote: Have you tried turning off the validation by setting the PERL_NO_VALIDATION environment variable? John, thanks for the pointer. I see this is documented in Params::Validate. I'd never thought of looking in Params::Validate docs to find out how to disable DateTime's use of it. It might be useful to include a pointer to this "feature" in DateTime's docs. If people want to make use of this it'd be nice to find a slightly smaller hammer than an env var. Unfortunately Perl doesn't make this easy, since just because you want to turn off validation doesn't mean that CPAN modules you use which also use DateTime want to turn it off. Sigh. -dave /*=== VegGuide.Orgwww.BookIRead.com Your guide to all that's veg. My book blog ===*/
Re: DateTime.pm on a Diet
On Wed, 6 Jul 2005, John Siracusa wrote: 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). Yeah, I was thinking that we'd do something like this if we're going to turn this into an officially blessed implementation. I was assuming Rick just used AUTOLOAD for a quick proof of concept. I'll bet you could get another few percent by using string eval to generate the accessor methods... Or just hand-coding them. It's not like there's that many. -dave /*=== VegGuide.Orgwww.BookIRead.com Your guide to all that's veg. My book blog ===*/
Re: DateTime::TimeZone test patch to work with DateTime >= 0.29
On Wed, 6 Jul 2005, Daisuke Maki wrote: DateTime 0.29 made changes to the date math wrt to DST, so tests that expected to fail when resulting datetime is invalid now are complaining. Sigh, fix one bug make another. I'm seriously considering reverting the change I made in 0.29 anyway, since it produces really weird results in many cases. -dave /*=== VegGuide.Orgwww.BookIRead.com Your guide to all that's veg. My book blog ===*/
Re: DateTime.pm on a Diet
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 RateDateTime 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. RateDateTime DateTime::Diet DateTime::Diet2 DateTime 1629/s ---47%-53% DateTime::Diet 3049/s 87% ---11% DateTime::Diet2 3436/s111% 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(5, { ' 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(1, { ' 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; }, });
Re: DateTime.pm on a Diet
I've used this approach in Date::Set. It runs the same test suite of DateTime::Event::ICal, in one third of the time. - Flavio S. Glock 2005/7/6, Rick Measham <[EMAIL PROTECTED]>: > > 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.
Re: DateTime.pm on a Diet
Le 5 juil. 05 à 15:15, John Siracusa a écrit : On 7/5/05 7:04 AM, Eric Cholet wrote: A while ago we did some profiling of an app that uses DateTime extensively and found out that most of the time is spent in Params::Validate. I understand this is somewhat of a religious issue, but in this case it's a net loss for us: the params have been validated zillions of times, and we lose performance in production. I would love a DateTime sans param validation. Have you tried turning off the validation by setting the PERL_NO_VALIDATION environment variable? John, thanks for the pointer. I see this is documented in Params::Validate. I'd never thought of looking in Params::Validate docs to find out how to disable DateTime's use of it. It might be useful to include a pointer to this "feature" in DateTime's docs. -- Eric Cholet
Re: DateTime.pm on a Diet
> Geoffrey, if you're reading this, I'd love your comments on how useful > this would be in your case. I am :) ok, I haven't looked at the code yet, but from your explanations it sounds attractive, especially in our situation. just like you, we don't necessarily need data validation since the data is coming mostly from database date/time fields. also similarly we would be creating objects for sql fields that may be infrequently manipulated in the codebase itself. so, take the overhead out of those kinds of things and you've made half my case for me :) the only sticking point would be the date math "exceptions" dave mentions. in my particular situation we deal with slices of time - the exact time of an event, when that event is visible on the web, what that time looks like to our servers on the west coast versus data entry on the east coast versus an attendee in australia, etc - so it's the date math that is driving force behind using DateTime in the first place. in essence, optimize away, but exploding object size when you need to do something real with it isn't much of a win. anyway, I hope you guys are taking my opinions appropriately - DateTime is clearly the right choice for perl DT logic IMHO for a variety of reasons, but I wasn't able to convince others to adopt it since their criteria for "right choice" was significantly different. so it's their arguments and mindset that I'm trying to convey :) --Geoff
Re: DateTime.pm on a Diet
On 7/5/05 11:09 PM, Rick Measham wrote: > I have written a module I tentatively call DateTime::Diet that helps > with this. I use DateTime in all sort of projects including hooks in > Class::DBI where many many table records all become DateTime objects, > even if I don't need the column that represents a DateTime. After bumping into the cost (CPU and memory) of creating DateTime objects for each date-like column in a database row, my solution was to have my OO/DB mapper module defer the "inflation" process until I actually ask for a DateTime object. I'm not using Class::DBI, but I believe it has a similar ability (although I'm not sure if it can "round-trip" from and back into the database without any inflation). Anyway, just chalk this up to another example of working around the overhead of creating many, many DateTime objects. I looked at speeding up DateTime->new a while ago (over a year I think) and a few things were done (by Dave, I think) to make it a lot faster, but I've stuck with my deferred inflation system because, as fast as new() gets, it's still faster to do nothing at all. -John
[RESEND] DateTime::TimeZone test patch to work with DateTime >= 0.29
(Resending out of fear that mail from my other account will get rejected) DateTime 0.29 made changes to the date math wrt to DST, so tests that expected to fail when resulting datetime is invalid now are complaining. I haven't checked all the tests yet, but here's at least one... Index: t/09changes.t === RCS file: /cvsroot/perl-date-time/modules/DateTime-TimeZone/t/09changes.t,v retrieving revision 1.15 diff -d -u -r1.15 09changes.t --- t/09changes.t 20 Oct 2003 15:11:47 - 1.15 +++ t/09changes.t 6 Jul 2005 06:55:31 - @@ -313,9 +313,12 @@ hour => 2, time_zone => 'America/Chicago', ); - -eval { $dt->add( days => 1 ) }; -like( $@, qr/Invalid local time .+/, 'exception for invalid time produced via add' ); +SKIP: { +skip 'DateTime >= 0.29 does not have this problem', 1 if +$DateTime::VERSION >= 0.29; +eval { $dt->add( days => 1 ) }; +like( $@, qr/Invalid local time .+/, 'exception for invalid time produced via add' ); +} } {
Re: DateTime.pm on a Diet
Dave Rolsky wrote: I'm not sure what you mean. It's much quicker for operations that occur before the rebless. If you were to keep using that object for further operations, the speed increase given from calling one "diet" method would fade into background noise. True. I expected a quicker degeneration, but was quite surprised. The point of DateTime::Diet was to be able to quickly create lots of DateTime-able objects. The implementation means that they transparently convert to being full DateTime object whenever you need to do anything with them. But this might be useful for cases where people have to create lots of objects, they don't care about time zones, and they rarely have to use the "advanced" DT.pm methods (math, time zones, etc). Almost agree. It's a subtle difference to me between creating lots of object and doing things with them. When I link to a database, the link turns dates into object. However I don't need to do anything with most of them. For example, I don't need to compare them, as I'd have done that in SQL. From there, I can still access the objects as if they were full blown DateTime objects because they will become such objects when they need to. I suspect people would want to be able to use this in conjunction with a parser like DT::Format::MySQL or something, where they know the data in the DB represents real datetimes. Exactly. My thought is that this sort of module is ideally suited here. We know the data is a real datetime so the validation isn't needed. We're (potentially) creating lots of objects and so the time/memory overhead saving is useful. Geoffrey, if you're reading this, I'd love your comments on how useful this would be in your case. Of course at the moment I'm just handling the simplest of setters and getters, but there's no reason why we couldn't include some other things like strptime, ymd, datetime etc. (Strptime would be interesting as it would need to failover to DateTime on some patterns) The main thing would be not to increase the amount of time it takes to create the object, so there'd be no math (that relies on month lengths, leap years, DST etc). The most data this will hold is that which can be passed to DateTime->new(). Cheers! Rick Measham