コンテンツにスキップ

Utils

Collections of utility functions for easybench.

ResultType

Bases: TypedDict

Type of benchmark result.

Source code in easybench/utils.py
16
17
18
19
20
21
class ResultType(TypedDict):
    """Type of benchmark result."""

    times: NotRequired[list[float]]
    memory: NotRequired[list[float]]
    output: NotRequired[list[object]]

StatType

Bases: TypedDict

Type of benchmark statistics.

Source code in easybench/utils.py
24
25
26
27
28
29
30
31
class StatType(TypedDict):
    """Type of benchmark statistics."""

    avg: NotRequired[float]
    min: NotRequired[float]
    max: NotRequired[float]
    avg_memory: NotRequired[float]
    max_memory: NotRequired[float]

calculate_statistics(results)

Calculate statistics from benchmark results.

引数:

名前 タイプ デスクリプション デフォルト
results ResultsType

Dictionary of benchmark results

必須

戻り値:

タイプ デスクリプション
StatsType

Dictionary of calculated statistics

ソースコード位置: easybench/utils.py
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
def calculate_statistics(
    results: ResultsType,
) -> StatsType:
    """
    Calculate statistics from benchmark results.

    Args:
        results: Dictionary of benchmark results

    Returns:
        Dictionary of calculated statistics

    """
    stats: StatsType = {}
    for method_name, data in results.items():
        if "times" in data and len(data["times"]) != 0:
            times = data["times"]
            stats[method_name] = {
                "avg": sum(times) / len(times),
                "min": min(times),
                "max": max(times),
            }
        else:
            stats[method_name] = {}

        if "memory" in data and len(data["memory"]) != 0:
            memory_values = data["memory"]
            avg_memory = sum(memory_values) / len(memory_values)
            max_memory = max(memory_values)
            stats[method_name].update(
                {"avg_memory": avg_memory, "max_memory": max_memory},
            )

    return stats

get_bench_env()

Collect environment information relevant to benchmarking.

戻り値:

タイプ デスクリプション
dict[str, Any]

Dictionary containing benchmark-relevant environment details

ソースコード位置: easybench/utils.py
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
def get_bench_env() -> dict[str, Any]:
    """
    Collect environment information relevant to benchmarking.

    Returns:
        Dictionary containing benchmark-relevant environment details

    """
    env_info: dict[str, Any] = {}

    # OS information (affects performance)
    env_info["os"] = {
        "system": platform.system(),
        "release": platform.release(),
        "version": platform.version(),
        "architecture": platform.architecture()[0],
        "machine": platform.machine(),
    }

    # CPU information (major performance factor)
    env_info["cpu"] = {
        "count": os.cpu_count() or "Unknown",
        "processor": platform.processor(),
    }

    # Python runtime environment (affects execution speed)
    env_info["python"] = {
        "version": platform.python_version(),
        "implementation": platform.python_implementation(),
        "compiler": platform.python_compiler(),
    }

    # Add Pyodide info if applicable
    if "pyodide" in sys.modules:
        pyodide = sys.modules["pyodide"]
        env_info["python"]["environment"] = "pyodide"
        env_info["python"]["pyodide_version"] = getattr(
            pyodide,
            "__version__",
            "unknown",
        )

    # Performance counter information (affects measurement precision)
    perf_info = time.get_clock_info("perf_counter")
    env_info["perf_counter"] = {
        "resolution": perf_info.resolution,
        "implementation": perf_info.implementation,
        "monotonic": perf_info.monotonic,
        "timer_overhead": measure_timer_overhead(),
    }

    return env_info

measure_timer_overhead(iterations=1000000)

Measure the overhead of the time.perf_counter() function.

ソースコード位置: easybench/utils.py
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
def measure_timer_overhead(iterations: int = 1_000_000) -> float:
    """Measure the overhead of the time.perf_counter() function."""
    # Variable to prevent loop optimization
    counter = 0

    # 1. Measure loop overhead only
    start_empty = time.perf_counter()
    for _ in range(iterations):
        counter += 1
    end_empty = time.perf_counter()
    loop_overhead = end_empty - start_empty

    # 2. Measure loop with timer calls
    start_with_timer = time.perf_counter()
    for _ in range(iterations):
        counter += 1
        time.perf_counter()
    end_with_timer = time.perf_counter()
    total_time = end_with_timer - start_with_timer

    # 3. Calculate timer function overhead
    # Use `counter` instead of `iterations` in the calculation
    # to ensure loop and variable are not optimized away in any interpreter
    return (total_time - loop_overhead) / (counter / 2)

visual_ljust(text, width, fillchar=' ')

Ljust for visual width.

引数:

名前 タイプ デスクリプション デフォルト
text str

The input string to pad.

必須
width int

Target visual width.

必須
fillchar str

Character used for padding. Defaults to a space.

' '

戻り値:

名前 タイプ デスクリプション
str str

Padded string with the specified visual width.

ソースコード位置: easybench/utils.py
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
def visual_ljust(text: str, width: int, fillchar: str = " ") -> str:
    """
    Ljust for visual width.

    Args:
        text (str): The input string to pad.
        width (int): Target visual width.
        fillchar (str, optional): Character used for padding. Defaults to a space.

    Returns:
        str: Padded string with the specified visual width.

    """
    current_width = visual_width(text)
    padding_width = max(0, width - current_width)
    return text + (fillchar * padding_width)

visual_rjust(text, width, fillchar=' ')

Rjust for visual width.

引数:

名前 タイプ デスクリプション デフォルト
text str

The input string to pad.

必須
width int

Target visual width.

必須
fillchar str

Character used for padding. Defaults to a space.

' '

戻り値:

名前 タイプ デスクリプション
str str

Right-padded string with the specified visual width.

ソースコード位置: easybench/utils.py
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
def visual_rjust(text: str, width: int, fillchar: str = " ") -> str:
    """
    Rjust for visual width.

    Args:
        text (str): The input string to pad.
        width (int): Target visual width.
        fillchar (str, optional): Character used for padding. Defaults to a space.

    Returns:
        str: Right-padded string with the specified visual width.

    """
    current_width = visual_width(text)
    padding_width = max(0, width - current_width)
    return (fillchar * padding_width) + text

visual_width(text)

Calculate the visual width of a string.

Assuming
  • Fullwidth ('F') and Wide ('W') characters count as 2.
  • All other characters count as 1.

This function is useful for determining display width, especially for East Asian characters in fixed-width terminal environments.

引数:

名前 タイプ デスクリプション デフォルト
text str

The input string.

必須

戻り値:

名前 タイプ デスクリプション
int int

The total visual width of the string.

ソースコード位置: easybench/utils.py
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
def visual_width(text: str) -> int:
    """
    Calculate the visual width of a string.

    Assuming:
        - Fullwidth ('F') and Wide ('W') characters count as 2.
        - All other characters count as 1.

    This function is useful for determining display width, especially for
    East Asian characters in fixed-width terminal environments.

    Args:
        text (str): The input string.

    Returns:
        int: The total visual width of the string.

    """
    width = 0
    for ch in text:
        ea_width = unicodedata.east_asian_width(ch)
        if ea_width in ("F", "W"):  # Fullwidth or Wide
            width += 2
        else:
            width += 1  # Narrow, Halfwidth, Ambiguous, Neutral
    return width