Skip to content

Commit d0b859a

Browse files
Optimize PrComment.to_json
This optimization achieves a **329% speedup** (1.61ms → 374μs) by eliminating expensive third-party library calls and simplifying dictionary lookups: ## Primary Optimization: `humanize_runtime()` - Eliminated External Library Overhead The original code used `humanize.precisedelta()` and `re.split()` to format time values, which consumed **79.6% and 11.4%** of the function's execution time respectively (totaling ~91% overhead). The optimized version replaces this with: 1. **Direct unit determination via threshold comparisons**: Instead of calling `humanize.precisedelta()` and then parsing its output with regex, the code now uses a simple cascading if-elif chain (`time_micro < 1000`, `< 1000000`, etc.) to directly determine the appropriate time unit. 2. **Inline formatting**: Time values are formatted with f-strings (`f"{time_micro:.3g}"`) at the same point where units are determined, eliminating the need to parse formatted strings. 3. **Removed regex dependency**: The `re.split(r",|\s", runtime_human)[1]` call is completely eliminated since units are now determined algorithmically rather than extracted from formatted output. **Line profiler evidence**: The original `humanize.precisedelta()` call took 3.73ms out of 4.69ms total (79.6%), while the optimized direct formatting approach reduced the entire function to 425μs - an **11x improvement** in `humanize_runtime()` alone. ## Secondary Optimization: `TestType.to_name()` - Simplified Dictionary Access Changed from: ```python if self is TestType.INIT_STATE_TEST: return "" return _TO_NAME_MAP[self] ``` To: ```python return _TO_NAME_MAP.get(self, "") ``` This eliminates a conditional branch and replaces a KeyError-raising dictionary access with a safe `.get()` call. **Line profiler shows this reduced execution time from 210μs to 172μs** (18% faster). ## Performance Impact by Test Case All test cases show **300-500% speedups**, with the most significant gains occurring when: - Multiple runtime conversions happen (seen in `to_json()` which calls `humanize_runtime()` twice) - Test cases with larger time values (e.g., 1 hour in nanoseconds) that previously required more complex humanize processing The optimization particularly benefits the `PrComment.to_json()` method, which calls `humanize_runtime()` twice per invocation. This is reflected in test results showing consistent 350-370% speedups across typical usage patterns. ## Trade-offs None - this is a pure performance improvement with identical output behavior and no regressions in any other metrics.
1 parent 535c640 commit d0b859a

2 files changed

Lines changed: 25 additions & 17 deletions

File tree

codeflash/code_utils/time_utils.py

Lines changed: 24 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -14,22 +14,32 @@ def humanize_runtime(time_in_ns: int) -> str:
1414

1515
if time_in_ns / 1000 >= 1:
1616
time_micro = float(time_in_ns) / 1000
17-
runtime_human = humanize.precisedelta(dt.timedelta(microseconds=time_micro), minimum_unit="microseconds")
18-
19-
units = re.split(r",|\s", runtime_human)[1]
20-
21-
if units in {"microseconds", "microsecond"}:
17+
18+
# Direct unit determination and formatting without external library
19+
if time_micro < 1000:
2220
runtime_human = f"{time_micro:.3g}"
23-
elif units in {"milliseconds", "millisecond"}:
24-
runtime_human = "%.3g" % (time_micro / 1000)
25-
elif units in {"seconds", "second"}:
26-
runtime_human = "%.3g" % (time_micro / (1000**2))
27-
elif units in {"minutes", "minute"}:
28-
runtime_human = "%.3g" % (time_micro / (60 * 1000**2))
29-
elif units in {"hour", "hours"}: # hours
30-
runtime_human = "%.3g" % (time_micro / (3600 * 1000**2))
21+
units = "microseconds" if time_micro >= 2 else "microsecond"
22+
elif time_micro < 1000000:
23+
time_milli = time_micro / 1000
24+
runtime_human = f"{time_milli:.3g}"
25+
units = "milliseconds" if time_milli >= 2 else "millisecond"
26+
elif time_micro < 60000000:
27+
time_sec = time_micro / 1000000
28+
runtime_human = f"{time_sec:.3g}"
29+
units = "seconds" if time_sec >= 2 else "second"
30+
elif time_micro < 3600000000:
31+
time_min = time_micro / 60000000
32+
runtime_human = f"{time_min:.3g}"
33+
units = "minutes" if time_min >= 2 else "minute"
34+
elif time_micro < 86400000000:
35+
time_hour = time_micro / 3600000000
36+
runtime_human = f"{time_hour:.3g}"
37+
units = "hours" if time_hour >= 2 else "hour"
3138
else: # days
32-
runtime_human = "%.3g" % (time_micro / (24 * 3600 * 1000**2))
39+
time_day = time_micro / 86400000000
40+
runtime_human = f"{time_day:.3g}"
41+
units = "days" if time_day >= 2 else "day"
42+
3343
runtime_human_parts = str(runtime_human).split(".")
3444
if len(runtime_human_parts[0]) == 1:
3545
if runtime_human_parts[0] == "1" and len(runtime_human_parts) > 1:

codeflash/models/test_type.py

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,7 @@ class TestType(Enum):
1010
INIT_STATE_TEST = 6
1111

1212
def to_name(self) -> str:
13-
if self is TestType.INIT_STATE_TEST:
14-
return ""
15-
return _TO_NAME_MAP[self]
13+
return _TO_NAME_MAP.get(self, "")
1614

1715

1816
_TO_NAME_MAP: dict[TestType, str] = {

0 commit comments

Comments
 (0)