From 3d4fb02e2907b2532333fdb5eefe6335c7cd94c4 Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Mon, 17 Aug 2020 15:26:11 +0200 Subject: [PATCH] ninjabackend: optimize ninja_quote Use regular expressions to quickly weed out strings that require quoting On a QEMU build the time spent in ninja_quote goes from 1.978s to 1.281s, with str.replace being kicked completely out of the profile. --- mesonbuild/backend/ninjabackend.py | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/mesonbuild/backend/ninjabackend.py b/mesonbuild/backend/ninjabackend.py index b4ebdc389..5f7f03a67 100644 --- a/mesonbuild/backend/ninjabackend.py +++ b/mesonbuild/backend/ninjabackend.py @@ -114,13 +114,17 @@ rsp_threshold = get_rsp_threshold() # from, etc.), so it must not be shell quoted. raw_names = {'DEPFILE_UNQUOTED', 'DESC', 'pool', 'description', 'targetdep'} +NINJA_QUOTE_BUILD_PAT = re.compile(r"[$ :\n]") +NINJA_QUOTE_VAR_PAT = re.compile(r"[$ \n]") + def ninja_quote(text, is_build_line=False): if is_build_line: - qcs = ('$', ' ', ':') + quote_re = NINJA_QUOTE_BUILD_PAT else: - qcs = ('$', ' ') - for char in qcs: - text = text.replace(char, '$' + char) + quote_re = NINJA_QUOTE_VAR_PAT + # Fast path for when no quoting is necessary + if not quote_re.search(text): + return text if '\n' in text: errmsg = '''Ninja does not support newlines in rules. The content was: @@ -128,7 +132,7 @@ def ninja_quote(text, is_build_line=False): Please report this error with a test case to the Meson bug tracker.'''.format(text) raise MesonException(errmsg) - return text + return quote_re.sub(r'$\g<0>', text) @unique class Quoting(Enum):