0
# Timing and Performance
1
2
High-precision timing utilities for performance measurement and profiling using Python's `perf_counter()` for accurate timing. Includes context manager support, multiple timing runs with statistical analysis, and configurable output formatting for development and optimization workflows.
3
4
## Capabilities
5
6
### Timer Class
7
8
High-precision timer class for measuring code execution time with support for multiple measurements and statistical analysis.
9
10
```python { .api }
11
class Timer:
12
"""
13
High-precision timer for performance measurement using perf_counter().
14
"""
15
def __init__(self, name=None, verbose=True, file=None, dp=3):
16
"""
17
Initialize Timer instance.
18
19
Parameters:
20
- name: Optional name for the timer (default: None)
21
- verbose: Print timing results automatically (default: True)
22
- file: Output file for timing messages (default: stdout)
23
- dp: Decimal places for timing display (default: 3)
24
"""
25
26
def __call__(self, name=None, verbose=None) -> Timer:
27
"""
28
Update timer configuration and return self for chaining.
29
30
Parameters:
31
- name: Update timer name (optional)
32
- verbose: Update verbose setting (optional)
33
34
Returns:
35
Self for method chaining
36
"""
37
38
def start(self, name=None, verbose=None) -> Timer:
39
"""
40
Start a new timing measurement.
41
42
Parameters:
43
- name: Name for this timing run (overrides instance name)
44
- verbose: Print result when captured (overrides instance verbose)
45
46
Returns:
47
Self for method chaining
48
"""
49
50
def capture(self, verbose=None) -> TimerResult:
51
"""
52
Stop the current timing measurement and optionally print result.
53
54
Parameters:
55
- verbose: Print timing result (overrides instance verbose)
56
57
Returns:
58
TimerResult object containing the timing data
59
"""
60
61
def summary(self, verbose=False) -> list[float]:
62
"""
63
Print summary statistics of all timing measurements.
64
65
Parameters:
66
- verbose: Print individual timing results in addition to summary
67
68
Returns:
69
List of elapsed times from all measurements
70
"""
71
72
def __enter__(self) -> Timer:
73
"""
74
Context manager entry - starts timing.
75
76
Returns:
77
Self for context manager protocol
78
"""
79
80
def __exit__(self, *args) -> None:
81
"""
82
Context manager exit - captures timing result.
83
84
Parameters:
85
- *args: Exception information (ignored)
86
"""
87
```
88
89
Usage examples:
90
91
```python
92
from devtools import Timer
93
94
# Basic timer usage
95
timer = Timer()
96
timer.start('operation')
97
# ... some code to time ...
98
result = timer.capture()
99
print(f"Elapsed: {result.elapsed():.3f}s")
100
101
# Named timer with context manager
102
with Timer('database query'):
103
# ... database operation ...
104
pass
105
# Output: database query: 0.123s elapsed
106
107
# Multiple timing runs with statistics
108
timer = Timer('sorting algorithm')
109
for i in range(10):
110
timer.start()
111
# ... sorting operation ...
112
timer.capture()
113
114
times = timer.summary(verbose=True)
115
# Output: Individual times and summary statistics
116
117
# Quiet timer (no automatic printing)
118
quiet_timer = Timer('background task', verbose=False)
119
with quiet_timer:
120
# ... background work ...
121
pass
122
result = quiet_timer.results[-1]
123
print(f"Background task took: {result.elapsed():.2f}s")
124
```
125
126
### TimerResult Class
127
128
Represents a single timing measurement with methods for accessing and formatting the timing data.
129
130
```python { .api }
131
class TimerResult:
132
"""
133
Represents a single timing measurement result.
134
"""
135
def __init__(self, name=None, verbose=True):
136
"""
137
Initialize TimerResult.
138
139
Parameters:
140
- name: Optional name for this timing result
141
- verbose: Whether this result should be printed automatically
142
"""
143
144
def capture(self) -> None:
145
"""
146
Record the end time for this measurement.
147
Must be called to finalize the timing result.
148
"""
149
150
def elapsed(self) -> float:
151
"""
152
Get the elapsed time in seconds.
153
154
Returns:
155
Elapsed time in seconds, or -1 if not yet captured
156
"""
157
158
def str(self, dp=3) -> str:
159
"""
160
Format timing result as string.
161
162
Parameters:
163
- dp: Number of decimal places to display (default: 3)
164
165
Returns:
166
Formatted timing string with name and elapsed time
167
"""
168
169
def __str__(self) -> str:
170
"""
171
String representation using default decimal places.
172
173
Returns:
174
Formatted timing string
175
"""
176
```
177
178
Usage examples:
179
180
```python
181
from devtools import Timer
182
183
# Manual timing result handling
184
timer = Timer(verbose=False)
185
timer.start('manual timing')
186
# ... some operation ...
187
result = timer.capture()
188
189
print(f"Operation name: {result._name}")
190
print(f"Elapsed time: {result.elapsed():.6f}s")
191
print(f"Formatted: {result.str(dp=6)}")
192
193
# Check if timing is complete
194
if result.elapsed() > 0:
195
print("Timing completed successfully")
196
```
197
198
### Context Manager Usage
199
200
Timer supports Python's context manager protocol for convenient timing of code blocks:
201
202
```python
203
from devtools import Timer
204
205
# Simple context manager timing
206
with Timer():
207
# Code to time
208
import time
209
time.sleep(0.1)
210
# Output: 0.100s elapsed
211
212
# Named context manager timing
213
with Timer('file processing'):
214
with open('large_file.txt', 'r') as f:
215
data = f.read()
216
processed = data.upper()
217
# Output: file processing: 0.045s elapsed
218
219
# Nested timing
220
with Timer('outer operation'):
221
# Some setup code
222
with Timer('inner operation'):
223
# Critical section
224
pass
225
# Some cleanup code
226
# Output: inner operation: 0.001s elapsed
227
# outer operation: 0.015s elapsed
228
```
229
230
### Multiple Timing Runs
231
232
Timer can collect multiple timing measurements and provide statistical analysis:
233
234
```python
235
from devtools import Timer
236
237
# Benchmark a function with multiple runs
238
def benchmark_function():
239
# Function to benchmark
240
return sum(i*i for i in range(1000))
241
242
timer = Timer('benchmark')
243
244
# Run multiple times
245
for run in range(100):
246
timer.start(f'run {run+1}')
247
result = benchmark_function()
248
timer.capture(verbose=False) # Don't print individual runs
249
250
# Get summary statistics
251
times = timer.summary()
252
# Output: 100 times: mean=0.001s stdev=0.000s min=0.001s max=0.002s
253
254
print(f"Average time: {sum(times)/len(times):.6f}s")
255
print(f"Fastest run: {min(times):.6f}s")
256
print(f"Slowest run: {max(times):.6f}s")
257
```
258
259
### Integration with Debug System
260
261
Timer integrates seamlessly with the debug system:
262
263
```python
264
from devtools import debug
265
266
# Timer created via debug instance
267
with debug.timer('database operation'):
268
# Database code here
269
pass
270
271
# Access timer methods through debug
272
timer = debug.timer('custom timer', verbose=False, dp=6)
273
with timer:
274
# Precise timing with 6 decimal places
275
pass
276
```
277
278
### Performance Considerations
279
280
The Timer class uses `time.perf_counter()` which provides:
281
282
- **High resolution**: Best available timer resolution on the platform
283
- **Monotonic**: Not affected by system clock adjustments
284
- **Precision**: Suitable for measuring short intervals (microseconds)
285
- **Consistency**: Reliable across different operating systems
286
287
```python
288
import time
289
from devtools import Timer
290
291
# Timing very short operations
292
with Timer('short operation'):
293
# Even very fast operations can be timed accurately
294
x = [i for i in range(100)]
295
# Output: short operation: 0.000s elapsed (shows microsecond precision)
296
297
# Timing longer operations
298
with Timer('long operation'):
299
time.sleep(1.0)
300
# Output: long operation: 1.000s elapsed
301
```
302
303
### Custom Output Formatting
304
305
Timer output can be customized through initialization parameters:
306
307
```python
308
from devtools import Timer
309
import sys
310
311
# Timer with custom output file and precision
312
with Timer('file operation', dp=6, file=sys.stderr):
313
with open('test.txt', 'w') as f:
314
f.write('test data')
315
# Output to stderr: file operation: 0.001234s elapsed
316
317
# Completely silent timer for programmatic use
318
timer = Timer(verbose=False)
319
with timer:
320
# ... operation ...
321
pass
322
323
# Access results programmatically
324
last_result = timer.results[-1]
325
if last_result.elapsed() > 0.1:
326
print("Operation was slow!")
327
```
328
329
## Types
330
331
```python { .api }
332
# Type alias for string return values
333
StrType = str
334
335
# Timer results storage
336
results: list[TimerResult] # List of all timing results for a Timer instance
337
```