Well here's an interesting thing. With yet another example of building filenames out of localtime kicking around, I thought I'd build a benchmark once and for all to show how much faster using an anonymous sub than the other techniques. This is the code I wrote:

#! /usr/bin/perl -w use strict; use POSIX; use Benchmark; sub via_anonsub { sub { sprintf '%04d%02d%02d%02d%02d%02d%05d', $_[5]+1900, $_[4]+1, $_[3], $_[2], $_[1], $_[0], $$ }->(localtime()) } sub via_sprintf { my @time = localtime(); sprintf '%04d%02d%02d%02d%02d%02d%05d', $time[5]+1900, $time[4]+1, $time[3], $time[2], $time[1], $time[0], + $$ } sub via_concat { my @time = localtime(); $time[4]++; $time[5]+=1900; $time[$_] = $time[$_]<10? "0".$time[$_]:$time[$_] for (0..5); my $filename = $time[5].$time[4].$time[3].$time[2].$time[1].$time[0] +.$$ } sub via_posix { strftime( "%Y%m%d%H%M%S$$", localtime() ) } print <<"PROOF"; via_concat: ${\via_concat()} via_anonsub: ${\via_anonsub()} via_posix: ${\via_posix()} via_sprintf: ${\via_sprintf()} PROOF timethese( shift || 10000, { 'via_anonsub' => \&via_anonsub, 'via_concat' => \&via_concat, 'via_posix' => \&via_posix, 'via_sprintf' => \&via_sprintf, });

When run on an older Perl (v5.005_03) this produces the following output:

$ perl filename 200000 via_concat: 2002091114542256876 via_anonsub: 2002091114542256876 via_posix: 2002091114542256876 via_sprintf: 2002091114542256876 Benchmark: timing 200000 iterations of via_anonsub, via_concat, via_po +six, via_sprintf... via_anonsub: 7 wallclock secs ( 5.60 usr + 0.28 sys = 5.88 CPU) via_concat: 21 wallclock secs (18.71 usr + 0.55 sys = 19.27 CPU) via_posix: 13 wallclock secs ( 9.59 usr + 0.62 sys = 10.20 CPU) via_sprintf: 10 wallclock secs ( 6.67 usr + 0.39 sys = 7.06 CPU)

But just for kicks, I thought I'd take it for a spin on a new machine running 5.8.0 and see what change, if any, appeared. I changed the code (the benchmark code, not the underlying snippets) a bit to use cmpthese instead, and this gives:

via_concat: 2002091114275977636 via_anonsub: 2002091114275977636 via_posix: 2002091114275977636 via_sprintf: 2002091114275977636 Benchmark: running via_anonsub, via_concat, via_posix, via_sprintf for + at least 10 CPU seconds... via_anonsub: 12 wallclock secs (10.12 usr + 0.51 sys = 10.62 CPU) @ 5 +3156.42/s (n=564787) via_concat: 10 wallclock secs (10.20 usr + 0.24 sys = 10.44 CPU) @ 3 +0435.83/s (n=317674) via_posix: 10 wallclock secs ( 9.57 usr + 0.93 sys = 10.50 CPU) @ 6 +0954.29/s (n=640020) via_sprintf: 10 wallclock secs (10.20 usr + 0.33 sys = 10.53 CPU) @ 4 +4919.45/s (n=473058) Rate via_concat via_sprintf via_anonsub via_posix via_concat 30436/s -- -32% -43% -50% via_sprintf 44919/s 48% -- -15% -26% via_anonsub 53156/s 75% 18% -- -13% via_posix 60954/s 100% 36% 15% --

I'm bummed. Somewhere along the line of perl's evolution, the performance of POSIX got better and/or the handling of subroutine calls got worse. Oh well, you can't always use POSIX, and this anonymous subroutine approach works well for other system calls that return multiple values, such as stat and getpwnam. And I can live with 15% ineffeciency I guess. Such is life.


update: It's faster because it doesn't have to deal with building up and tearing down lexicals. And the sub is compiled at, ah, compile time. That's why it should be faster. Look more closely at the code; I'm not building closures.

I used to assume that using POSIX was slower because it was XS code and paying the XS/Perl boundary-crossing cost. Either calling XS is now cheaper, or creating lexicals is now more expensive, relatively speaking.


print@_{sort keys %_},$/if%_=split//,'= & *a?b:e\f/h^h!j+n,o@o;r$s-t%t#u'

In reply to Re: Timestamp as a Filename Collection by grinder
in thread Timestamp as a Filename Collection by hiseldl

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.