From e8498e480088b3a7d6e3ea239bdf66ba496118d4 Mon Sep 17 00:00:00 2001 From: Adrien Cacciaguerra Date: Thu, 6 Nov 2025 10:42:10 +0100 Subject: [PATCH 1/2] feat: improve time unit display in local walltime --- src/pytest_codspeed/instruments/walltime.py | 35 ++++++++++++++++++++- tests/test_format_time.py | 35 +++++++++++++++++++++ 2 files changed, 69 insertions(+), 1 deletion(-) create mode 100644 tests/test_format_time.py diff --git a/src/pytest_codspeed/instruments/walltime.py b/src/pytest_codspeed/instruments/walltime.py index e2c5815..f85f857 100644 --- a/src/pytest_codspeed/instruments/walltime.py +++ b/src/pytest_codspeed/instruments/walltime.py @@ -359,7 +359,7 @@ def _print_benchmark_table(self) -> None: rsd_text.stylize("red bold") table.add_row( escape(bench.name), - f"{bench.stats.min_ns / bench.stats.iter_per_round:,.0f}ns", + format_time(bench.stats.min_ns / bench.stats.iter_per_round), rsd_text, f"{bench.stats.total_time:,.2f}s", f"{bench.stats.iter_per_round * bench.stats.rounds:,}", @@ -377,3 +377,36 @@ def get_result_dict(self) -> dict[str, Any]: }, "benchmarks": [asdict(bench) for bench in self.benchmarks], } + + +def format_time(time_ns: float) -> str: + """Format time in nanoseconds to a human-readable string with appropriate units. + + Args: + time_ns: Time in nanoseconds + + Returns: + Formatted string with appropriate unit (ns, µs, ms, or s) + + Examples: + >>> format_time(123) + '123ns' + >>> format_time(1_234) + '1.23µs' + >>> format_time(76_126_625) + '76.1ms' + >>> format_time(2_500_000_000) + '2.50s' + """ + if time_ns < 1_000: + # Less than 1 microsecond - show in nanoseconds + return f"{time_ns:.0f}ns" + elif time_ns < 1_000_000: + # Less than 1 millisecond - show in microseconds + return f"{time_ns / 1_000:.2f}µs" + elif time_ns < 1_000_000_000: + # Less than 1 second - show in milliseconds + return f"{time_ns / 1_000_000:.1f}ms" + else: + # 1 second or more - show in seconds + return f"{time_ns / 1_000_000_000:.2f}s" diff --git a/tests/test_format_time.py b/tests/test_format_time.py new file mode 100644 index 0000000..e374871 --- /dev/null +++ b/tests/test_format_time.py @@ -0,0 +1,35 @@ +"""Tests for the time formatting function.""" + +import pytest + +from pytest_codspeed.instruments.walltime import format_time + + +@pytest.mark.parametrize( + "time_ns,expected", + [ + # Nanoseconds (< 1,000 ns) + (0, "0ns"), + (1, "1ns"), + (123, "123ns"), + (999, "999ns"), + # Microseconds (1,000 ns - 999,999 ns) + (1_000, "1.00µs"), + (1_234, "1.23µs"), + (10_500, "10.50µs"), + (999_999, "1000.00µs"), + # Milliseconds (1,000,000 ns - 999,999,999 ns) + (1_000_000, "1.0ms"), + (76_126_625, "76.1ms"), + (75_860_833, "75.9ms"), + (500_000_000, "500.0ms"), + (999_999_999, "1000.0ms"), + # Seconds (>= 1,000,000,000 ns) + (1_000_000_000, "1.00s"), + (2_500_000_000, "2.50s"), + (10_000_000_000, "10.00s"), + ], +) +def test_format_time(time_ns: float, expected: str) -> None: + """Test that format_time correctly formats time values with appropriate units.""" + assert format_time(time_ns) == expected From bb84077c947d27c53e0336cfedcf1dc90a305d41 Mon Sep 17 00:00:00 2001 From: Adrien Cacciaguerra Date: Thu, 13 Nov 2025 15:33:23 +0100 Subject: [PATCH 2/2] chore: add comment to explain results storing in .codspeed folder --- src/pytest_codspeed/plugin.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/pytest_codspeed/plugin.py b/src/pytest_codspeed/plugin.py index a91f07e..26a0ca1 100644 --- a/src/pytest_codspeed/plugin.py +++ b/src/pytest_codspeed/plugin.py @@ -300,6 +300,9 @@ def pytest_sessionfinish(session: pytest.Session, exitstatus): if plugin.profile_folder: result_path = plugin.profile_folder / "results" / f"{os.getpid()}.json" else: + # Default to a .codspeed folder in the root of the project. + # Storing the results will be later used for features such as + # local comparison between runs. result_path = ( session.config.rootpath / f".codspeed/results_{time() * 1000:.0f}.json" )