jffry has asked for the wisdom of the Perl Monks concerning the following question:

I want to remove the time stamp from the scalar context return value of localtime(). Like you might see in the %changelog section of an RPM spec file. That is, convert this:

Thu Dec 17 15:55:52 2009

To this:

Thu Dec 17 2009

To me, it just begs to be yanked out as the 4th whitespace-delimited field. So I did this:

my $now = localtime; my @t = split /\s+/, $now; splice @t, 3, 1; $now = join ' ', @t;

But these 3 data type transitions made me wonder if I'm being ridiculously wasteful.

Just thought of this, for a comparison.

my $now = localtime; $now =~ s/(\d\d:){2}\d\d//; $now =~ s/\s{2,}/ /;

Here is the run time (1,000,000 iterations) of the s// operator solution.

real 0m2.700s user 0m2.698s sys 0m0.002s

Here is the run time of my split, splice, join solution.

real 0m4.576s user 0m4.573s sys 0m0.002s

Looks to be 1.7 times faster.

Am I missing anything?

EDIT:Oh, yeah. If I can I want this all on one line (neatly) because this part of a big hash initialization, and I'd rather not have the localtime string modification off somewhere else since it is not used anywhere else.

  • Comment on Using split, splice, and join to remove time from scalar context return of localtime()
  • Select or Download Code

Replies are listed 'Best First'.
Re: Using split, splice, and join to remove time from scalar context return of localtime()
by Fletch (Bishop) on Dec 17, 2009 at 21:49 UTC

    You're forgetting that POSIX has a strftime routine that can generate the desired format directly rather than mushing up a string.

    The cake is a lie.
    The cake is a lie.
    The cake is a lie.

      Got it. Thanks!

      use POSIX qw (strftime); $now = strftime('%a %b %e %Y', localtime);
Re: Using split, splice, and join to remove time from scalar context return of localtime()
by ikegami (Patriarch) on Dec 17, 2009 at 22:30 UTC

    There's also strftime in POSIX.

    $ perl -MPOSIX=strftime -le'print strftime "%a %b %e %Y", localtime' Thu Dec 17 2009

    You could also use substr to remove the unwanted parts.

    $ perl -le'substr(my $now = localtime, 11, 9, ""); print $now' Thu Dec 17 2009

    Benchmark results

    Rate splice strftime slice subst substr splice 93974/s -- -23% -40% -49% -64% strftime 121619/s 29% -- -23% -33% -53% slice 157894/s 68% 30% -- -14% -40% subst 182658/s 94% 50% 16% -- -30% substr 261283/s 178% 115% 65% 43% --

    It surprises me that strftime is slower than slice and subst.

    There's no surprise that substr is the fastest, but I don't know if it's safe. strftime is of course the safest.

    Honestly, though. I don't see how the difference in speed observed could possibly matter in practice.

    Benchmark code:

    use strict; use warnings; use Benchmark qw( cmpthese ); use POSIX qw( strftime ); sub using_splice { my @t = split /\s/, $_[0]; splice @t, 3, 1; return join ' ', @t; } sub using_slice { return join " ", ( split " ", $_[0] )[0,1,2,4]; } my %tests = ( splice => 'my $now = using_splice(scalar(localtime));', slice => 'my $now = using_slice(scalar(localtime));', subst => '( my $now = localtime ) =~ s/(?:\d\d:){2}\d\d //;', strftime => 'my $now = strftime("%a %b %d %Y", localtime);', substr => 'substr(my $now = localtime, 11, 9, "");', ); $_ = "use strict; use warnings; $_" for values %tests; cmpthese(-3, \%tests);

    Update: Added slice. Improved subst.

Re: Using split, splice, and join to remove time from scalar context return of localtime()
by BrowserUk (Patriarch) on Dec 17, 2009 at 22:05 UTC

    How about:

    [0] Perl> $now = substr localtime(), 11, 8;; [0] Perl> print $now;; 21:59:52

    Should be way faster than either of the other methods. It's method a in these results:

    Rate b c a b 121/s -- -37% -70% c 191/s 58% -- -53% a 405/s 235% 112% --

    Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
    "Science is about questioning the status quo. Questioning authority".
    In the absence of evidence, opinion is indistinguishable from prejudice.
      Without any use locale, does localtime use the current locale?

        I've no idea. To either the question or it's relevance.

        But if it doesn't, I'd say that was a bug in Perl or the pragma.


        Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
        "Science is about questioning the status quo. Questioning authority".
        In the absence of evidence, opinion is indistinguishable from prejudice.
Re: Using split, splice, and join to remove time from scalar context return of localtime()
by jwkrahn (Abbot) on Dec 17, 2009 at 23:15 UTC
    my $now = localtime; my @t = split /\s/, $now; splice @t, 3, 1; $now = join ' ', @t;

    That won't work very well during the first nine days of the month:

    $ perl -le' my $now = localtime 1260043200; print $now; my @t = split /\s/, $now; splice @t, 3, 1; $now = join " ", @t; print $now; ' Sat Dec 5 12:00:00 2009 Sat Dec 12:00:00 2009

      Nice one! I forgot the "+" in my @t = split /\s+/, $now; That would have been an ugly bug.

        That's why I used split " " in my benchmark. I didn't stop to think if such a situation existed, but I figured it would be safer.