executiontimer 1.0.3__py3-none-any.whl → 1.1.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -18,7 +18,7 @@ from execution_timer._timer import (
18
18
  save_execution_timings_json,
19
19
  )
20
20
 
21
- __version__ = "1.0.3"
21
+ __version__ = "1.1.0"
22
22
 
23
23
  __all__ = [
24
24
  "DEFAULT_CATEGORY",
execution_timer/_timer.py CHANGED
@@ -198,11 +198,11 @@ class _ExecutionTimer:
198
198
  # Total the unflattened paths, like get_total_time and the JSON export.
199
199
  total_time = _top_level_time(snapshot)
200
200
  timings = _flatten(snapshot) if flatten else snapshot
201
- report = [f"Total time: {total_time:.4f} s.\n"]
201
+ report = [f"Total time: {_format_duration(total_time)}.\n"]
202
202
  for key, depth in _ordered_by_hierarchy(timings):
203
203
  elapsed_time = timings[key]["elapsed_time"]
204
204
  percentage = (elapsed_time / total_time) * 100 if total_time else 0.0
205
- report.append(f"{'.. ' * depth}{key[-1]}: {elapsed_time:.4f} s ({percentage:.2f}%)")
205
+ report.append(f"{'.. ' * depth}{key[-1]}: {_format_duration(elapsed_time)} ({percentage:.2f}%)")
206
206
  return "\n".join(report)
207
207
 
208
208
  def compute_total_time(self) -> float:
@@ -243,6 +243,20 @@ class _ExecutionTimer:
243
243
  _TIMER: Final = _ExecutionTimer()
244
244
 
245
245
 
246
+ def _format_duration(seconds: float) -> str:
247
+ """Format seconds with three decimals in the largest of µs, ms and s that stays below 1000.
248
+
249
+ The unit is chosen after rounding, so 999.9996 µs reads ``1.000 ms`` rather than
250
+ ``1000.000 µs``. Sections of any length stay readable, where fixed seconds would show a
251
+ fast section as zero.
252
+ """
253
+ for scale, unit in ((1e6, "µs"), (1e3, "ms")):
254
+ scaled = seconds * scale
255
+ if round(scaled, 3) < 1000:
256
+ return f"{scaled:.3f} {unit}"
257
+ return f"{seconds:.3f} s"
258
+
259
+
246
260
  def _flatten(timings: dict[tuple[str, ...], _TimesDict]) -> dict[tuple[str, ...], _TimesDict]:
247
261
  flat_map: dict[tuple[str, ...], _TimesDict] = {}
248
262
  for key, info in timings.items():
@@ -378,8 +392,9 @@ def _basic_name_without_counter(name: str) -> str:
378
392
  def get_execution_times_report(*, flatten: bool = True) -> str:
379
393
  """Get a formatted, indented report of all recorded sections.
380
394
 
381
- Each line shows a section's accumulated seconds and its share of the total time.
382
- Indentation reflects nesting.
395
+ Each line shows a section's accumulated time and its share of the total time.
396
+ Indentation reflects nesting. Times have three decimals, in ``µs``, ``ms`` or ``s``,
397
+ whichever keeps the number below 1000.
383
398
 
384
399
  Args:
385
400
  flatten: Merge ``counter`` variants such as ``step[0]`` and ``step[1]`` into ``step``.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: executiontimer
3
- Version: 1.0.3
3
+ Version: 1.1.0
4
4
  Summary: Hierarchical execution timing with user-defined categories.
5
5
  Project-URL: Homepage, https://github.com/seba2390/ExecutionTimer
6
6
  Project-URL: Documentation, https://seba2390.github.io/ExecutionTimer/
@@ -84,12 +84,12 @@ print(get_execution_times_report())
84
84
  ```
85
85
 
86
86
  ```text
87
- Total time: 0.3156 s.
87
+ Total time: 312.838 ms.
88
88
 
89
- load_data: 0.1219 s (38.62%)
90
- solve: 0.1937 s (61.38%)
91
- .. step: 0.1585 s (50.24%)
92
- .. postprocess: 0.0350 s (11.10%)
89
+ load_data: 124.682 ms (39.85%)
90
+ solve: 188.157 ms (60.15%)
91
+ .. step: 154.718 ms (49.46%)
92
+ .. postprocess: 33.295 ms (10.64%)
93
93
  ```
94
94
 
95
95
  `TimerContext` also works as a decorator, including on `async def` functions:
@@ -0,0 +1,7 @@
1
+ execution_timer/__init__.py,sha256=HrXnAPwlQzzTpSRBVk_j-OLc-RNRS3WluU9XpUxLRh4,959
2
+ execution_timer/_timer.py,sha256=oLbiDVmmojeijwPMy99wVFwCLTGQ8ND2Gck3wh_SVRs,22043
3
+ execution_timer/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
4
+ executiontimer-1.1.0.dist-info/METADATA,sha256=YAEpYJjuaKvtbdKyyhje1lLgqyKlkYKYb-7hYoDt7q0,4966
5
+ executiontimer-1.1.0.dist-info/WHEEL,sha256=W3fkpkm7-wf9vBI5Z-7s0eWkeM-spu78I8Neb98DeEg,87
6
+ executiontimer-1.1.0.dist-info/licenses/LICENSE,sha256=rkJbDOYRrUX8k3S55pPiEquJXZGh07KvD01F1sBBppw,1077
7
+ executiontimer-1.1.0.dist-info/RECORD,,
@@ -1,7 +0,0 @@
1
- execution_timer/__init__.py,sha256=chCRC3XhPx8siDmgixnvyOGEfS1-6LOQOKv7e6s6hLs,959
2
- execution_timer/_timer.py,sha256=ld91tKWPwAm5ewK35hBljdqfMGkgf7LxeDL2l9GlWwg,21372
3
- execution_timer/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
4
- executiontimer-1.0.3.dist-info/METADATA,sha256=Lh0LaMQBbmoTkGM4k_x2JKBe6Q95sSW-esmDjOTIfgg,4957
5
- executiontimer-1.0.3.dist-info/WHEEL,sha256=W3fkpkm7-wf9vBI5Z-7s0eWkeM-spu78I8Neb98DeEg,87
6
- executiontimer-1.0.3.dist-info/licenses/LICENSE,sha256=rkJbDOYRrUX8k3S55pPiEquJXZGh07KvD01F1sBBppw,1077
7
- executiontimer-1.0.3.dist-info/RECORD,,