git-svn: lazy load some modules
We can delay loading some modules until we need them for uncommon code paths. For example, persistent memoization is not often needed, so we can avoid loading the modules for it until we encounter svn::mergeinfo during fetch. This gives a tiny reduction in syscalls (from 15641 to 15305) when running "git svn info" and counting via "strace -fc". Further, more invasive work will be needed to noticeably improve performance. Signed-off-by: Eric Wong <normalperson@yhbt.net>
Eric Wong committed
Jan 15, 2015 at 08:54 UTC
47092c10671da906ae626634dc83beb29ce76a9d
5 files changed
+26
-20
git-svn.perl
+7
-6
@@ -11,14 +11,10 @@ $AUTHOR = 'Eric Wong <normalperson@yhbt.net>';
11
$VERSION = '@@GIT_VERSION@@';
12
13
use Carp qw/croak/;
14
-use Digest::MD5;
15
-use IO::File qw//;
14
use File::Basename qw/dirname basename/;
15
use File::Path qw/mkpath/;
16
use File::Spec;
19
-use File::Find;
17
use Getopt::Long qw/:config gnu_getopt no_ignore_case auto_abbrev/;
21
-use IPC::Open3;
18
use Memoize;
19
20
use Git::SVN;
@@ -298,7 +294,6 @@ my %cmd = (
294
{} ],
295
);
296
301
-use Term::ReadLine;
297
package FakeTerm;
298
sub new {
299
my ($class, $reason) = @_;
@@ -313,6 +308,7 @@ package main;
308
my $term;
309
sub term_init {
310
$term = eval {
311
+ require Term::ReadLine;
312
$ENV{"GIT_SVN_NOTTY"}
313
? new Term::ReadLine 'git-svn', \*STDIN, \*STDOUT
314
: new Term::ReadLine 'git-svn';
@@ -1173,6 +1169,7 @@ sub cmd_branch {
1169
}
1170
1171
::_req_svn();
1172
+ require SVN::Client;
1173
1174
my $ctx = SVN::Client->new(
1175
config => SVN::Core::config_get_config(
@@ -1693,11 +1690,13 @@ sub cmd_reset {
1690
}
1691
1692
sub cmd_gc {
1693
+ require File::Find;
1694
if (!can_compress()) {
1695
warn "Compress::Zlib could not be found; unhandled.log " .
1696
"files will not be compressed.\n";
1697
}
1700
- find({ wanted => \&gc_directory, no_chdir => 1}, "$ENV{GIT_DIR}/svn");
1698
+ File::Find::find({ wanted => \&gc_directory, no_chdir => 1},
1699
+ "$ENV{GIT_DIR}/svn");
1700
}
1701
1702
########################### utility functions #########################
@@ -2122,6 +2121,7 @@ sub find_file_type_and_diff_status {
2121
sub md5sum {
2122
my $arg = shift;
2123
my $ref = ref $arg;
2124
+ require Digest::MD5;
2125
my $md5 = Digest::MD5->new();
2126
if ($ref eq 'GLOB' || $ref eq 'IO::File' || $ref eq 'File::Temp') {
2127
$md5->addfile($arg) or croak $!;
@@ -2148,6 +2148,7 @@ sub gc_directory {
2148
$gz->gzwrite($str) or
2149
die "Unable to write: ".$gz->gzerror()."!\n";
2150
}
2151
+ no warnings 'once'; # $File::Find::name would warn
2152
unlink $_ or die "unlink $File::Find::name: $!\n";
2153
} elsif (-f $_ && basename($_) eq "index") {
2154
unlink $_ or die "unlink $_: $!\n";
perl/Git/SVN.pm
+13
-9
@@ -9,10 +9,8 @@ use vars qw/$_no_metadata
9
$_use_log_author $_add_author_from $_localtime/;
10
use Carp qw/croak/;
11
use File::Path qw/mkpath/;
12
-use File::Copy qw/copy/;
12
use IPC::Open3;
13
use Memoize; # core since 5.8.0, Jul 2002
15
-use Memoize::Storable;
14
use POSIX qw(:signal_h);
15
16
use Git qw(
@@ -32,11 +30,7 @@ use Git::SVN::Utils qw(
30
add_path_to_url
31
);
32
35
-my $can_use_yaml;
36
-BEGIN {
37
- $can_use_yaml = eval { require Git::SVN::Memoize::YAML; 1};
38
-}
39
-
33
+my $memo_backend;
34
our $_follow_parent = 1;
35
our $_minimize_url = 'unset';
36
our $default_repo_id = 'svn';
@@ -1578,7 +1572,16 @@ sub tie_for_persistent_memoization {
1572
my $hash = shift;
1573
my $path = shift;
1574
1581
- if ($can_use_yaml) {
1575
+ unless ($memo_backend) {
1576
+ if (eval { require Git::SVN::Memoize::YAML; 1}) {
1577
+ $memo_backend = 1;
1578
+ } else {
1579
+ require Memoize::Storable;
1580
+ $memo_backend = -1;
1581
+ }
1582
+ }
1583
+
1584
+ if ($memo_backend > 0) {
1585
tie %$hash => 'Git::SVN::Memoize::YAML', "$path.yaml";
1586
} else {
1587
tie %$hash => 'Memoize::Storable', "$path.db", 'nstore';
@@ -2188,8 +2191,9 @@ sub rev_map_set {
2191
# both of these options make our .rev_db file very, very important
2192
# and we can't afford to lose it because rebuild() won't work
2193
if ($self->use_svm_props || $self->no_metadata) {
2194
+ require File::Copy;
2195
$sync = 1;
2192
- copy($db, $db_lock) or die "rev_map_set(@_): ",
2196
+ File::Copy::copy($db, $db_lock) or die "rev_map_set(@_): ",
2197
"Failed to copy: ",
2198
"$db => $db_lock ($!)\n";
2199
} else {
perl/Git/SVN/Editor.pm
+1
-2
@@ -5,7 +5,6 @@ use warnings;
5
use SVN::Core;
6
use SVN::Delta;
7
use Carp qw/croak/;
8
-use IO::File;
8
use Git qw/command command_oneline command_noisy command_output_pipe
9
command_input_pipe command_close_pipe
10
command_bidi_pipe command_close_bidi_pipe/;
@@ -586,7 +585,7 @@ The interface will change as git-svn evolves.
585
=head1 DEPENDENCIES
586
587
Subversion perl bindings,
589
-the core L<Carp> and L<IO::File> modules,
588
+the core L<Carp> module,
589
and git's L<Git> helper module.
590
591
C<Git::SVN::Editor> has not been tested using callers other than
perl/Git/SVN/Fetcher.pm
+1
-2
@@ -7,7 +7,6 @@ use warnings;
7
use SVN::Delta;
8
use Carp qw/croak/;
9
use File::Basename qw/dirname/;
10
-use IO::File qw//;
10
use Git qw/command command_oneline command_noisy command_output_pipe
11
command_input_pipe command_close_pipe
12
command_bidi_pipe command_close_bidi_pipe/;
@@ -600,7 +599,7 @@ developing git-svn.
599
=head1 DEPENDENCIES
600
601
L<SVN::Delta> from the Subversion perl bindings,
603
-the core L<Carp>, L<File::Basename>, and L<IO::File> modules,
602
+the core L<Carp> and L<File::Basename> modules,
603
and git's L<Git> helper module.
604
605
C<Git::SVN::Fetcher> has not been tested using callers other than
perl/Git/SVN/Ra.pm
+4
-1
@@ -3,7 +3,6 @@ use vars qw/@ISA $config_dir $_ignore_refs_regex $_log_window_size/;
3
use strict;
4
use warnings;
5
use Memoize;
6
-use SVN::Client;
6
use Git::SVN::Utils qw(
7
canonicalize_url
8
canonicalize_path
@@ -42,6 +41,7 @@ END {
41
}
42
43
sub _auth_providers () {
44
+ require SVN::Client;
45
my @rv = (
46
SVN::Client::get_simple_provider(),
47
SVN::Client::get_ssl_server_trust_file_provider(),
@@ -247,7 +247,10 @@ sub get_log {
247
$ret;
248
}
249
250
+# uncommon, only for ancient SVN (<= 1.4.2)
251
sub trees_match {
252
+ require IO::File;
253
+ require SVN::Client;
254
my ($self, $url1, $rev1, $url2, $rev2) = @_;
255
my $ctx = SVN::Client->new(auth => _auth_providers);
256
my $out = IO::File->new_tmpfile;