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:
But I've been trying out
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.
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
.That sounds like a winner, doesn't it? But it left me some questions.state
declares a lexically scoped variable, just likemy
. However, those variables will never be reinitialized, contrary to lexical variables that are reinitialized each time their enclosing block is entered.
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.
#!/usr/bin/perl 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; SHOW TABLES SQL sub outside { my $arrayref = db_arrayref( $sql ) ; } sub use_my { my $sql = <<SQL; SHOW TABLES SQL my $arrayref = db_arrayref( $sql ) ; } sub use_state { state $sql = <<SQL; SHOW TABLES SQL my $arrayref = db_arrayref( $sql ) ; } timethese( 10_000 , { 'outside' => sub { outside( ) ; } , 'use my' => sub { use_my( ) ; } , 'use state' => sub { use_state( ) ; } , } ) ;
DB.pm 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