[p4perl] P4.pm performance concerns
Luke Petre
lpetre at insomniacgames.com
Wed Jul 6 16:16:04 PDT 2005
I have a script that potentially can sync a very large number of files
and so I'd like to display progress in a friendly manner to the user.
Basically I take a list of directories I need to sync, do a sync preview
to figure out how many files there are, sync those files and update a
percentage along the way.
But I'm worried that calling $client->Sync for each file will be
prohibitably expensive, vs. calling Sync once and passing an array of
all the files in.
My code (pardon the formatting):
sub SyncDirectories
{
my ($directories, $slow) = @_;
my $start_time = time;
# open a connection to perforce
my $p4 = new P4;
$p4->Connect() or die( "\n * Failed to connect to Perforce\n" );
# preview sync
my @files_to_sync = $p4->Run( "sync", "-n", @$directories );
# get a list of files to sync
@files_to_sync = map { /(.*\#\d+) -/; $1; } @files_to_sync;
if ( $slow )
{
# sync each file, updating the percentage along the way
print( "\n o Sync Progress: " );
my $percentage = 0;
print( sprintf( "%3d%%", $percentage ) );
my $count = 0;
foreach my $file ( @files_to_sync )
{
$p4->Run( "sync", $file );
my $new_percentage = int ( ($count++ / @files_to_sync) * 100 );
if ( $new_percentage > $percentage )
{
$percentage = $new_percentage;
print( "\010\010\010\010" );
print( sprintf( "%3d%%", $percentage ) );
}
}
print( "\010\010\010\010" );
print( sprintf( "100%%\n", $percentage ) );
}
elsif ( @files_to_sync > 0 )
{
# sync files wholesale
$p4->Run( "sync", @files_to_sync );
}
$p4->Disconnect();
my $total_time = time - $start_time;
my $num_files = @files_to_sync;
print( "\n o SyncDirectories got $num_files files, took $total_time
seconds\n" );
}
I ran this function in a loop on the same set of files, syncing those
files to revision 0 in between calls to SyncDirectories. The set of
files is about 500KB, and I have compress turned on in my clientspec.
with slow = 0:
o SyncDirectories got 97 files, took 0 seconds
o SyncDirectories got 97 files, took 1 seconds
o SyncDirectories got 97 files, took 1 seconds
o SyncDirectories got 97 files, took 0 seconds
o SyncDirectories got 97 files, took 0 seconds
with slow = 1:
o SyncDirectories got 97 files, took 22 seconds
o SyncDirectories got 97 files, took 21 seconds
o SyncDirectories got 97 files, took 21 seconds
o SyncDirectories got 97 files, took 23 seconds
o SyncDirectories got 97 files, took 22 seconds
With a larger set of files (253MB):
with slow = 0:
o SyncDirectories got 630 files, took 46 seconds
o SyncDirectories got 630 files, took 47 seconds
o SyncDirectories got 630 files, took 46 seconds
o SyncDirectories got 630 files, took 47 seconds
o SyncDirectories got 630 files, took 45 seconds
with slow = 1:
o SyncDirectories got 630 files, took 163 seconds
o SyncDirectories got 630 files, took 162 seconds
o SyncDirectories got 630 files, took 157 seconds
o SyncDirectories got 630 files, took 162 seconds
o SyncDirectories got 630 files, took 161 seconds
At this point I'm considering calling "p4 -x <tmpfile> sync" twice, and
parsing the output. Only because I expect that I'll get both the
performance and the nice progress display that I want.
I'm completely open to suggestions on how better to use the module.
If I were to request a new feature I guess I would like to be able to do
something like:
$p4->SetOutput( \&HandleOutput );
$p4->Run( "sync", @files_to_sync );
And handle each line of the output to update the percentage. Thoughts?
Luke
More information about the p4perl
mailing list