Hi!

While testing an application that generates SQL based on data extracted
from a database, I noticed that about 80% of the runtime was being
consumed by DBI::db::quote().  A significant portion of that was in
DBD::_::db::type_info().  By caching the results of type_info_all() (which
type_info() calls repeatedly), and by memoizing type_info() itself, I was
able to speed it up 5x or so.

I have appended the diffs to this message.  (I don't know if defining new
DB handle attributes willy-nilly is the best way to cache these values, but
it's the best thing I could think of....)

-Dean Kopesky / Bridge Information Systems / [EMAIL PROTECTED]


*** DBI.pm      Mon Jun  4 14:01:39 2001
--- DBI.pm.2    Mon Jul  2 13:07:53 2001
***************
*** 1070,1079 ****
  
      sub type_info {
        my ($dbh, $data_type) = @_;
-       my $tia = $dbh->type_info_all;
-       return unless @$tia;
-       my $idx_hash = shift @$tia;
  
        my $dt_idx   = $idx_hash->{DATA_TYPE} || $idx_hash->{data_type};
        Carp::croak("type_info_all returned non-standard DATA_TYPE index value 
($dt_idx != 1)")
            if $dt_idx && $dt_idx != 1;
--- 1070,1087 ----
  
      sub type_info {
        my ($dbh, $data_type) = @_;
  
+       my $ti_cache = $dbh->{'TypeInfoCache'};
+       my $tia      = $dbh->{'TypeInfoAllCache'};
+       my $idx_hash = $dbh->{'IdxHashCache'};
+ 
+       if ( ! $idx_hash ) {
+               $dbh->{'TypeInfoCache'}    = $ti_cache = {};
+               $dbh->{'TypeInfoAllCache'} = $tia      = $dbh->type_info_all;
+               $dbh->{'IdxHashCache'}     = $idx_hash = shift @$tia;
+       }
+       return unless $idx_hash;
+ 
        my $dt_idx   = $idx_hash->{DATA_TYPE} || $idx_hash->{data_type};
        Carp::croak("type_info_all returned non-standard DATA_TYPE index value 
($dt_idx != 1)")
            if $dt_idx && $dt_idx != 1;
***************
*** 1082,1087 ****
--- 1090,1099 ----
        my @ti;
        my @data_type_list = (ref $data_type) ? @$data_type : ($data_type);
        foreach $data_type (@data_type_list) {
+             if ( exists $ti_cache->{$data_type} ) {
+               return $ti_cache->{$data_type}->[0] unless wantarray;
+               return @{$ti_cache->{$data_type}};
+           }
            if (defined($data_type) && $data_type != DBI::SQL_ALL_TYPES()) {
                push @ti, grep { $_->[$dt_idx] == $data_type } @$tia;
            }
***************
*** 1100,1105 ****
--- 1112,1120 ----
        my @out = map {
            my %h; @h{@idx_names} = @{$_}[ @idx_values ]; \%h;
        } @ti;
+ 
+       $ti_cache->{$data_type} = \@out;
+ 
        return $out[0] unless wantarray;
        return @out;
      }

Reply via email to