From 2408e2f42b0c522be867ad192c61f7d5f1553485 Mon Sep 17 00:00:00 2001 From: "codeflash-ai[bot]" <148906541+codeflash-ai[bot]@users.noreply.github.com> Date: Tue, 28 Oct 2025 05:16:24 +0000 Subject: [PATCH] Optimize parse_timedelta The optimized code achieves a **5% speedup** by eliminating unnecessary dictionary operations and reducing function call overhead: **Key optimizations:** 1. **Direct group access instead of groupdict()**: Rather than calling `parts.groupdict()` which creates a dictionary and then iterating through all possible keys, the code uses `parts.group()` directly for each known field ('weeks', 'days', 'hours', 'minutes', 'seconds'). This avoids dictionary allocation and the overhead of the `.items()` iteration. 2. **Conditional parameter building**: Uses walrus operator (`if (w := g('weeks')):`) to both check for matches and assign values in one step, only adding matched fields to `time_params`. This eliminates the need to check every possible key with `if p:` inside a loop. 3. **Early return optimization**: Adds a fast path that returns `dt.timedelta()` immediately if no parameters matched, avoiding an unnecessary function call with an empty dictionary. **Performance benefits by test type:** - **Invalid/empty strings** show the largest gains (10-14% faster) due to reduced overhead when no matches are found - **Single unit parsing** shows moderate gains (2-6% faster) from eliminating dictionary operations - **Multi-unit parsing** shows consistent but smaller gains (~2-4% faster) as the optimization impact is diluted across multiple matched fields The optimization is most effective for cases with few matched time units or invalid inputs, while maintaining identical behavior for all valid inputs. --- panel/util/__init__.py | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/panel/util/__init__.py b/panel/util/__init__.py index 79b712b0a6..904173699e 100644 --- a/panel/util/__init__.py +++ b/panel/util/__init__.py @@ -370,11 +370,23 @@ def parse_timedelta(time_str: str) -> dt.timedelta | None: parts = _period_regex.match(time_str) if not parts: return None - parts_dict = parts.groupdict() + + # Micro-optimization: Inline parts.groupdict() and predefine the possible fields to avoid unnecessary dict allocation, loop, and checks. + # The regex always names: 'weeks', 'days', 'hours', 'minutes', 'seconds' + g = parts.group + # Only include fields that matched and are not None. + # This avoids the .items() loop and 'if p' check for every possible key. time_params = {} - for (name, p) in parts_dict.items(): - if p: - time_params[name] = float(p) + if (w := g('weeks')): time_params['weeks'] = float(w) + if (d := g('days')): time_params['days'] = float(d) + if (h := g('hours')): time_params['hours'] = float(h) + if (m := g('minutes')): time_params['minutes'] = float(m) + if (s := g('seconds')): time_params['seconds'] = float(s) + + # Fast path if nothing was matched, to avoid unnecessary dt call + if not time_params: + return dt.timedelta() + return dt.timedelta(**time_params)