[Dbix-class] DBIx::Class::Fixtures speedup

Drew Taylor taylor.andrew.j at gmail.com
Wed Apr 23 12:14:59 BST 2008


I'm using Fixtures in my app, and am overall pleased with it. But I
now have a couple thousand fixture items which are imported, and
that's taking upwards of 1min+. Out of curiosity I commented out the
creation of the tmp_fixtures_dir and just read from fixtures_dir. I
shaved my populate() time in approximately half. What's the reasoning
for the tmp dir? Safety in case anything goes wrong? For me, it's just
a lot of wasted IOs and time. :-) Luke, any objections if I remove
this?

Also, I was able to shave off a few more seconds by switching to
gathering all the row data for a given source and then calling
$schema->populate(\@rows) so the insert_bulk functionality can be
used. castaway++

Here's the combined patch:

svn diff
Index: lib/DBIx/Class/Fixtures.pm
===================================================================
--- lib/DBIx/Class/Fixtures.pm	(revision 4288)
+++ lib/DBIx/Class/Fixtures.pm	(working copy)
@@ -792,20 +792,12 @@

   my $schema = $self->_generate_schema({ ddl => $ddl_file,
connection_details => delete $params->{connection_details}, %{$params}
});
   $self->msg("\nimporting fixtures");
-  my $tmp_fixture_dir = dir($fixture_dir, "-~populate~-" . $<);

   my $version_file = file($fixture_dir, '_dumper_version');
   unless (-e $version_file) {
 #     return DBIx::Class::Exception->throw('no version file found');
   }

-  if (-e $tmp_fixture_dir) {
-    $self->msg("- deleting existing temp directory $tmp_fixture_dir");
-    $tmp_fixture_dir->rmtree;
-  }
-  $self->msg("- creating temp dir");
-  dircopy(dir($fixture_dir, $schema->source($_)->from),
dir($tmp_fixture_dir, $schema->source($_)->from)) for grep { -e
dir($fixture_dir, $schema->source($_)->from) } $schema->sources;
-
   eval { $schema->storage->dbh->do('SET foreign_key_checks=0') };

   my $fixup_visitor;
@@ -829,6 +821,7 @@
     my $rs = $schema->resultset($source);
     my $source_dir = dir($tmp_fixture_dir, lc($rs->result_source->from));
     next unless (-e $source_dir);
+    my @rows;
     while (my $file = $source_dir->next) {
       next unless ($file =~ /\.fix$/);
       next if $file->is_dir;
@@ -836,8 +829,9 @@
       my $HASH1;
       eval($contents);
       $HASH1 = $fixup_visitor->visit($HASH1) if $fixup_visitor;
-      $rs->create($HASH1);
+      push @rows, $HASH1;
     }
+    $rs->populate(\@rows);
   }

   if ($params->{post_ddl}) {
@@ -851,7 +845,6 @@

   $self->msg("- fixtures imported");
   $self->msg("- cleaning up");
-  $tmp_fixture_dir->rmtree;
   eval { $schema->storage->dbh->do('SET foreign_key_checks=1') };

   return 1;


Drew
-- 
----------------------------------------------------------------
 Drew Taylor * Web development & consulting
 Email: drew at drewtaylor.com * Site implementation & hosting
 Web : www.drewtaylor.com * perl/mod_perl/DBI/mysql/postgres
 ----------------------------------------------------------------



More information about the DBIx-Class mailing list