From e70bcd46d0a8b0c7c095330f7a695f804337623e Mon Sep 17 00:00:00 2001 From: Albert Vaca Date: Thu, 20 Jun 2019 14:38:15 +0200 Subject: [PATCH 1/2] Do not compile regexes on each run - Keep a cache of already compiled regexes (they will always be the same) - Alphanumeric strings an be simply matched for `==` instead of using RE. --- .../datadog_checks/go_expvar/go_expvar.py | 34 +++++++++++++------ 1 file changed, 24 insertions(+), 10 deletions(-) diff --git a/go_expvar/datadog_checks/go_expvar/go_expvar.py b/go_expvar/datadog_checks/go_expvar/go_expvar.py index 83dbb78d016aa..5030c62c27b2c 100644 --- a/go_expvar/datadog_checks/go_expvar/go_expvar.py +++ b/go_expvar/datadog_checks/go_expvar/go_expvar.py @@ -63,6 +63,7 @@ class GoExpvar(AgentCheck): def __init__(self, name, init_config, agentConfig, instances=None): AgentCheck.__init__(self, name, init_config, agentConfig, instances) + self._regexes = {} self._last_gc_count = defaultdict(int) def _get_data(self, url, instance): @@ -226,18 +227,31 @@ def deep_get(self, content, keys, traversed_path=None): if keys == []: return [(traversed_path, content)] + results = [] + key = keys[0] - regex = "".join(["^", key, "$"]) - try: - key_rex = re.compile(regex) - except Exception: - self.warning("Cannot compile regex: %s" % regex) - return [] + if key.isalnum(): + # key is not a regex, simply match for equality + for new_key, new_content in self.items(content): + if key == new_key: + results.extend(self.deep_get(new_content, keys[1:], traversed_path + [str(new_key)])) + else: + # key might be a regex + key_rex = self._regexes.get(key) + if key_rex is None: + # we don't have it cached, compile it + regex = "".join(["^", key, "$"]) + try: + key_rex = re.compile(regex) + except Exception: + self.warning("Cannot compile regex: %s" % regex) + return [] + self._regexes[key] = key_rex + + for new_key, new_content in self.items(content): + if key_rex.match(new_key): + results.extend(self.deep_get(new_content, keys[1:], traversed_path + [str(new_key)])) - results = [] - for new_key, new_content in self.items(content): - if key_rex.match(new_key): - results.extend(self.deep_get(new_content, keys[1:], traversed_path + [str(new_key)])) return results def items(self, object): From 407d786c316c13f66a28ad50e5686940a9c0fb4b Mon Sep 17 00:00:00 2001 From: Albert Vaca Date: Thu, 20 Jun 2019 15:57:32 +0200 Subject: [PATCH 2/2] Deduplicate loop as per CR --- .../datadog_checks/go_expvar/go_expvar.py | 25 ++++++++----------- 1 file changed, 11 insertions(+), 14 deletions(-) diff --git a/go_expvar/datadog_checks/go_expvar/go_expvar.py b/go_expvar/datadog_checks/go_expvar/go_expvar.py index 5030c62c27b2c..6871c6a710dfd 100644 --- a/go_expvar/datadog_checks/go_expvar/go_expvar.py +++ b/go_expvar/datadog_checks/go_expvar/go_expvar.py @@ -227,31 +227,28 @@ def deep_get(self, content, keys, traversed_path=None): if keys == []: return [(traversed_path, content)] - results = [] - key = keys[0] if key.isalnum(): # key is not a regex, simply match for equality - for new_key, new_content in self.items(content): - if key == new_key: - results.extend(self.deep_get(new_content, keys[1:], traversed_path + [str(new_key)])) + matcher = key.__eq__ else: # key might be a regex - key_rex = self._regexes.get(key) - if key_rex is None: + key_regex = self._regexes.get(key) + if key_regex is None: # we don't have it cached, compile it - regex = "".join(["^", key, "$"]) + regex = "^{}$".format(key) try: - key_rex = re.compile(regex) + key_regex = re.compile(regex) except Exception: self.warning("Cannot compile regex: %s" % regex) return [] - self._regexes[key] = key_rex - - for new_key, new_content in self.items(content): - if key_rex.match(new_key): - results.extend(self.deep_get(new_content, keys[1:], traversed_path + [str(new_key)])) + self._regexes[key] = key_regex + matcher = key_regex.match + results = [] + for new_key, new_content in self.items(content): + if matcher(new_key): + results.extend(self.deep_get(new_content, keys[1:], traversed_path + [str(new_key)])) return results def items(self, object):