From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-15.7 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,FREEMAIL_FORGED_FROMDOMAIN,FREEMAIL_FROM, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 4331FC47082 for ; Sun, 23 May 2021 08:56:41 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 157BF6100B for ; Sun, 23 May 2021 08:56:41 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231738AbhEWI6F (ORCPT ); Sun, 23 May 2021 04:58:05 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:36850 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231721AbhEWI6A (ORCPT ); Sun, 23 May 2021 04:58:00 -0400 Received: from mail-wr1-x432.google.com (mail-wr1-x432.google.com [IPv6:2a00:1450:4864:20::432]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 2A078C06138E for ; Sun, 23 May 2021 01:56:33 -0700 (PDT) Received: by mail-wr1-x432.google.com with SMTP id p7so21572312wru.10 for ; Sun, 23 May 2021 01:56:33 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=CcqQsIoDgyi1uRVQSNdjT00K+sIWr/Tsq0tsQUXX18Y=; b=qvouc1HQ6YFw8Rtyb2bA4PHMjGG7LZGgJRQnqsa8FCpOAH6l4M/1YNRdkDVi+daR3G lCgTrXScCexl6vD3/lvbMNo9sRWr0EAIu1Cy9++zM9vURYk44Lr6HGjoRj1lIm3wtrbM W7cNpTL/hppmMRn8yB4rcoky/ZbbTvY3G2IJgyZg6iUK7JSw4bMsBMzJgcS4vTYkx+67 9wdOdbeVJt62jMPbhLE8GDnoIwmiSCpkfHxxK1jwIZKqrfVTNLG50j/wvFM92tA/Zp61 QmbUN62uPYBtkHHQvRD1iSQiFD7F8D0VLFp6Fjj5RAKeG9askqUE3YwvBry+ZOLom0BV ImzQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=CcqQsIoDgyi1uRVQSNdjT00K+sIWr/Tsq0tsQUXX18Y=; b=c761z3MxeIxr9xUer8tpqzBnB5p5sYSrpeW/eO5Uv5IgqhlgQVgbHHcFoUWznx6TTl 4jST46gfMR19+rbWnoiI8om3j8xV9sqCM1ZvwZGPTJhElrHqKgrF/vM/dn0IxGLr9prC 5lFF9RauQIx6BZykAKUmJBAOWuMsR/svQ87Ez2ZOxd3K0RysSyOk0UKRs2sq/4364+ZO NItXIkgo8e5JwY5HZiKzuFycQy3ixGyRm4DIQ8anj2UacjpurSKCfwiP+W9E2qEkMyXG tzGTpueVYxiC22uCBat7A713IWoDzNsrHRvWtlqKrtqRU+SNUduZLFXuGVelAOJVUMEu Kd/Q== X-Gm-Message-State: AOAM532IWabnfzY9ofLqK+iW7PHrRipzSLvnNEMCsWtApyVg9AIzVZqZ Zk8ghnS4euGDxeQr54SupR8E8cDzNXAOC65F X-Google-Smtp-Source: ABdhPJxiWfbjoCJjs5+w3EHQZF4NSaIUXMf3BQb3BbBTMDleGhdy/I4Cvd/SKzd5Vvpaiio+uoDemA== X-Received: by 2002:a05:6000:1189:: with SMTP id g9mr16833973wrx.385.1621760191446; Sun, 23 May 2021 01:56:31 -0700 (PDT) Received: from vm.nix.is (vm.nix.is. [2a01:4f8:120:2468::2]) by smtp.gmail.com with ESMTPSA id s15sm9577839wrt.54.2021.05.23.01.56.30 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 23 May 2021 01:56:30 -0700 (PDT) From: =?UTF-8?q?=C3=86var=20Arnfj=C3=B6r=C3=B0=20Bjarmason?= To: git@vger.kernel.org Cc: Junio C Hamano , Gregory Anders , =?UTF-8?q?=C4=90o=C3=A0n=20Tr=E1=BA=A7n=20C=C3=B4ng=20Danh?= , Jeff King , Eric Sunshine , Eric Wong , Felipe Contreras , =?UTF-8?q?=C3=86var=20Arnfj=C3=B6r=C3=B0=20Bjarmason?= Subject: [PATCH v3 12/13] send-email: move trivial config handling to Perl Date: Sun, 23 May 2021 10:56:17 +0200 Message-Id: X-Mailer: git-send-email 2.32.0.rc0.406.g05cb3eebfc In-Reply-To: References: MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Precedence: bulk List-ID: X-Mailing-List: git@vger.kernel.org Optimize the startup time of git-send-email by using an amended config_regexp() function to retrieve the list of config keys and values we're interested in. For boolean keys we can handle the [true|false] case ourselves, and the "--get" case didn't need any parsing. Let's leave "--path" and other "--bool" cases to "git config". I'm not bothering with the "undef" or "" case (true and false, respectively), let's just punt on those and others and have "git config --type=bool" handle it. This brings the runtime of "git send-email" from ~60-~70ms to a very steady ~40ms on my test box. We now run just one "git config" invocation on startup instead of 8, the exact number will differ based on the local sendemail.* config. I happen to have 8 of those set. This brings the runtime of t9001-send-email.sh from ~13s down to ~12s for me. The change there is less impressive as many of those tests set various config values, and we're also getting to the point of diminishing returns for optimizing "git send-email" itself. Signed-off-by: Ævar Arnfjörð Bjarmason diff --git a/git-send-email.perl b/git-send-email.perl index 1e9273fd4f..1ea4d9589d 100755 --- a/git-send-email.perl +++ b/git-send-email.perl @@ -324,7 +324,11 @@ sub read_config { my $target = $config_bool_settings{$setting}; my $key = "$prefix.$setting"; next unless exists $known_keys->{$key}; - my $v = Git::config_bool(@repo, $key); + my $v = (@{$known_keys->{$key}} == 1 && + (defined $known_keys->{$key}->[0] && + $known_keys->{$key}->[0] =~ /^(?:true|false)$/s)) + ? $known_keys->{$key}->[0] eq 'true' + : Git::config_bool(@repo, $key); next unless defined $v; next if $configured->{$setting}++; $$target = $v; @@ -353,14 +357,12 @@ sub read_config { my $key = "$prefix.$setting"; next unless exists $known_keys->{$key}; if (ref($target) eq "ARRAY") { - my @values = Git::config(@repo, $key); - next unless @values; + my @values = @{$known_keys->{$key}}; next if $configured->{$setting}++; @$target = @values; } else { - my $v = Git::config(@repo, $key); - next unless defined $v; + my $v = $known_keys->{$key}->[0]; next if $configured->{$setting}++; $$target = $v; } @@ -371,12 +373,19 @@ sub config_regexp { my ($regex) = @_; my @ret; eval { - @ret = Git::command( + my $ret = Git::command( 'config', - '--name-only', + '--null', '--get-regexp', $regex, ); + @ret = map { + # We must always return ($k, $v) here, since + # empty config values will be just "key\0", + # not "key\nvalue\0". + my ($k, $v) = split /\n/, $_, 2; + ($k, $v); + } split /\0/, $ret; 1; } or do { # If we have no keys we're OK, otherwise re-throw @@ -389,8 +398,10 @@ sub config_regexp { # parses 'bool' etc.) by only doing so for config keys that exist. my %known_config_keys; { - my @known_config_keys = config_regexp("^sende?mail[.]"); - @known_config_keys{@known_config_keys} = (); + my @kv = config_regexp("^sende?mail[.]"); + while (my ($k, $v) = splice @kv, 0, 2) { + push @{$known_config_keys{$k}} => $v; + } } # sendemail.identity yields to --identity. We must parse this --- git-send-email.perl | 29 ++++++++++++++++++++--------- 1 file changed, 20 insertions(+), 9 deletions(-) diff --git a/git-send-email.perl b/git-send-email.perl index 1e9273fd4f..1ea4d9589d 100755 --- a/git-send-email.perl +++ b/git-send-email.perl @@ -324,7 +324,11 @@ sub read_config { my $target = $config_bool_settings{$setting}; my $key = "$prefix.$setting"; next unless exists $known_keys->{$key}; - my $v = Git::config_bool(@repo, $key); + my $v = (@{$known_keys->{$key}} == 1 && + (defined $known_keys->{$key}->[0] && + $known_keys->{$key}->[0] =~ /^(?:true|false)$/s)) + ? $known_keys->{$key}->[0] eq 'true' + : Git::config_bool(@repo, $key); next unless defined $v; next if $configured->{$setting}++; $$target = $v; @@ -353,14 +357,12 @@ sub read_config { my $key = "$prefix.$setting"; next unless exists $known_keys->{$key}; if (ref($target) eq "ARRAY") { - my @values = Git::config(@repo, $key); - next unless @values; + my @values = @{$known_keys->{$key}}; next if $configured->{$setting}++; @$target = @values; } else { - my $v = Git::config(@repo, $key); - next unless defined $v; + my $v = $known_keys->{$key}->[0]; next if $configured->{$setting}++; $$target = $v; } @@ -371,12 +373,19 @@ sub config_regexp { my ($regex) = @_; my @ret; eval { - @ret = Git::command( + my $ret = Git::command( 'config', - '--name-only', + '--null', '--get-regexp', $regex, ); + @ret = map { + # We must always return ($k, $v) here, since + # empty config values will be just "key\0", + # not "key\nvalue\0". + my ($k, $v) = split /\n/, $_, 2; + ($k, $v); + } split /\0/, $ret; 1; } or do { # If we have no keys we're OK, otherwise re-throw @@ -389,8 +398,10 @@ sub config_regexp { # parses 'bool' etc.) by only doing so for config keys that exist. my %known_config_keys; { - my @known_config_keys = config_regexp("^sende?mail[.]"); - @known_config_keys{@known_config_keys} = (); + my @kv = config_regexp("^sende?mail[.]"); + while (my ($k, $v) = splice @kv, 0, 2) { + push @{$known_config_keys{$k}} => $v; + } } # sendemail.identity yields to --identity. We must parse this -- 2.32.0.rc0.406.g05cb3eebfc