From 41c271b8cbe19e45809a0a9d3f5426bc0b664e29 Mon Sep 17 00:00:00 2001 From: Ulf Magnusson Date: Wed, 7 Nov 2018 05:31:58 +0100 Subject: Add a fast path for string parsing For strings with no $ or \ in them (99.86% of all strings in the Linux x86 Kconfigs), we can just find() the matching quote directly. Saves a few % of tokenization time. --- kconfiglib.py | 45 +++++++++++++++++++++++++++------------------ 1 file changed, 27 insertions(+), 18 deletions(-) diff --git a/kconfiglib.py b/kconfiglib.py index 2e30486..9300444 100644 --- a/kconfiglib.py +++ b/kconfiglib.py @@ -1974,28 +1974,37 @@ class Kconfig(object): c = s[i] if c in "\"'": - s, end_i = self._expand_str(s, i) - - # os.path.expandvars() and the $UNAME_RELEASE replace() is - # a backwards compatibility hack, which should be - # reasonably safe as expandvars() leaves references to - # undefined env. vars. as is. - # - # The preprocessor functionality changed how environment - # variables are referenced, to $(FOO). - val = os.path.expandvars( - s[i + 1:end_i - 1].replace("$UNAME_RELEASE", - platform.uname()[2])) - - i = end_i + if "$" not in s and "\\" not in s: + # Fast path for lines without $ and \. Find the + # matching quote. + end_i = s.find(c, i + 1) + 1 + if not end_i: + self._parse_error("unterminated string") + val = s[i + 1:end_i - 1] + i = end_i + else: + # Slow path + s, end_i = self._expand_str(s, i) + + # os.path.expandvars() and the $UNAME_RELEASE replace() + # is a backwards compatibility hack, which should be + # reasonably safe as expandvars() leaves references to + # undefined env. vars. as is. + # + # The preprocessor functionality changed how + # environment variables are referenced, to $(FOO). + val = os.path.expandvars( + s[i + 1:end_i - 1].replace("$UNAME_RELEASE", + platform.uname()[2])) + + i = end_i # This is the only place where we don't survive with a # single token of lookback: 'option env="FOO"' does not # refer to a constant symbol named "FOO". - token = val \ - if token in _STRING_LEX or \ - tokens[0] is _T_OPTION else \ - self._lookup_const_sym(val) + token = \ + val if token in _STRING_LEX or tokens[0] is _T_OPTION \ + else self._lookup_const_sym(val) elif s.startswith("&&", i): token = _T_AND -- cgit v1.2.3