Cookie Notice

As far as I know, and as far as I remember, nothing in this page does anything with Cookies.


Enemy of the State?

I've been glad for all the new life breathed into the Perl community starting with 5.10, but, honestly, there has been only one thing I consistently used in the raft of new stuff added: say. I disliked having to write print "$var\n" each time I wanted to print a line with a newline, and say allowed me an easy way to do that without changing the behavior of print.

But I've been trying out state.
state declares a lexically scoped variable, just like my. However, those variables will never be reinitialized, contrary to lexical variables that are reinitialized each time their enclosing block is entered.
That sounds like a winner, doesn't it? But it left me some questions.

I deal with SQL a lot, and so I have queries in my code. Sometimes, big queries. I'm wondering if assigning the SQL query each time is more costly, CPU-wise, than declaring it as a state variable and just holding it in memory.


use feature qw{ say state } ;
use strict ;
use warnings ;
use Benchmark qw{:all} ;
use Carp ;

use lib '/home/jacoby/lib' ;
use DB ;

my $sql = <<SQL;

sub outside {
    my $arrayref = db_arrayref( $sql ) ;

sub use_my {
    my $sql = <<SQL;
    my $arrayref = db_arrayref( $sql ) ;

sub use_state {
    state $sql = <<SQL;
    my $arrayref = db_arrayref( $sql ) ;

    10_000 , {
    'outside'   => sub { outside( ) ; } ,
    'use my'    => sub { use_my( ) ; } ,
    'use state' => sub { use_state( ) ; } ,
    } ) ; is my wrapper for the very complex DBI module, which gives me just three functions: db_do, db_hashref and db_arrayref. DB has %prepared, such that $prepared{ $sql } = $dbh->prepare( $sql ), so that, when using a query over and over again, a pre-prepared statement handle object is passed out.
Benchmark: timing 10000 iterations of outside, use my, use state...
   outside: 476 wallclock secs (14.66 usr +  8.21 sys = 22.87 CPU) @ 437.25/s (n=10000)
    use my: 475 wallclock secs (14.87 usr +  8.01 sys = 22.88 CPU) @ 437.06/s (n=10000)
 use state: 469 wallclock secs (14.68 usr +  8.14 sys = 22.82 CPU) @ 438.21/s (n=10000)
Looks like, in this case, it doesn't make a whole lot of difference. Still, good to know, right?

No comments:

Post a Comment