Skip to content

Commit a27bd2e

Browse files
committed
Remove default duration
Instead of limiting profiling to 10s, let the process finish by default.
1 parent 86d9045 commit a27bd2e

File tree

2 files changed

+14
-14
lines changed

2 files changed

+14
-14
lines changed

Lib/profiling/sampling/cli.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -120,8 +120,8 @@ def _build_child_profiler_args(args):
120120
# Sampling options
121121
hz = MICROSECONDS_PER_SECOND // args.sample_interval_usec
122122
child_args.extend(["-r", str(hz)])
123-
child_args.extend(["-d", str(args.duration)])
124-
123+
if args.duration is not None:
124+
child_args.extend(["-d", str(args.duration)])
125125
if args.all_threads:
126126
child_args.append("-a")
127127
if args.realtime_stats:
@@ -356,9 +356,9 @@ def _add_sampling_options(parser):
356356
"-d",
357357
"--duration",
358358
type=int,
359-
default=10,
359+
default=None,
360360
metavar="SECONDS",
361-
help="Sampling duration",
361+
help="Sampling duration (default: run to completion)",
362362
)
363363
sampling_group.add_argument(
364364
"-a",

Lib/profiling/sampling/sample.py

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -76,18 +76,18 @@ def _new_unwinder(self, native, gc, opcodes, skip_non_matching_threads):
7676
)
7777
return unwinder
7878

79-
def sample(self, collector, duration_sec=10, *, async_aware=False):
79+
def sample(self, collector, duration_sec=None, *, async_aware=False):
8080
sample_interval_sec = self.sample_interval_usec / 1_000_000
81-
running_time = 0
8281
num_samples = 0
8382
errors = 0
8483
interrupted = False
84+
running_time_sec = 0
8585
start_time = next_time = time.perf_counter()
8686
last_sample_time = start_time
8787
realtime_update_interval = 1.0 # Update every second
8888
last_realtime_update = start_time
8989
try:
90-
while running_time < duration_sec:
90+
while duration_sec is None or running_time_sec < duration_sec:
9191
# Check if live collector wants to stop
9292
if hasattr(collector, 'running') and not collector.running:
9393
break
@@ -104,7 +104,7 @@ def sample(self, collector, duration_sec=10, *, async_aware=False):
104104
stack_frames = self.unwinder.get_stack_trace()
105105
collector.collect(stack_frames)
106106
except ProcessLookupError as e:
107-
duration_sec = current_time - start_time
107+
running_time_sec = current_time - start_time
108108
break
109109
except (RuntimeError, UnicodeDecodeError, MemoryError, OSError):
110110
collector.collect_failed_sample()
@@ -135,25 +135,25 @@ def sample(self, collector, duration_sec=10, *, async_aware=False):
135135
num_samples += 1
136136
next_time += sample_interval_sec
137137

138-
running_time = time.perf_counter() - start_time
138+
running_time_sec = time.perf_counter() - start_time
139139
except KeyboardInterrupt:
140140
interrupted = True
141-
running_time = time.perf_counter() - start_time
141+
running_time_sec = time.perf_counter() - start_time
142142
print("Interrupted by user.")
143143

144144
# Clear real-time stats line if it was being displayed
145145
if self.realtime_stats and len(self.sample_intervals) > 0:
146146
print() # Add newline after real-time stats
147147

148-
sample_rate = num_samples / running_time if running_time > 0 else 0
148+
sample_rate = num_samples / running_time_sec if running_time_sec > 0 else 0
149149
error_rate = (errors / num_samples) * 100 if num_samples > 0 else 0
150-
expected_samples = int(duration_sec / sample_interval_sec)
150+
expected_samples = int(running_time_sec / sample_interval_sec)
151151
missed_samples = (expected_samples - num_samples) / expected_samples * 100 if expected_samples > 0 else 0
152152

153153
# Don't print stats for live mode (curses is handling display)
154154
is_live_mode = LiveStatsCollector is not None and isinstance(collector, LiveStatsCollector)
155155
if not is_live_mode:
156-
print(f"Captured {num_samples:n} samples in {fmt(running_time, 2)} seconds")
156+
print(f"Captured {num_samples:n} samples in {fmt(running_time_sec, 2)} seconds")
157157
print(f"Sample rate: {fmt(sample_rate, 2)} samples/sec")
158158
print(f"Error rate: {fmt(error_rate, 2)}")
159159

@@ -166,7 +166,7 @@ def sample(self, collector, duration_sec=10, *, async_aware=False):
166166

167167
# Pass stats to flamegraph collector if it's the right type
168168
if hasattr(collector, 'set_stats'):
169-
collector.set_stats(self.sample_interval_usec, running_time, sample_rate, error_rate, missed_samples, mode=self.mode)
169+
collector.set_stats(self.sample_interval_usec, running_time_sec, sample_rate, error_rate, missed_samples, mode=self.mode)
170170

171171
if num_samples < expected_samples and not is_live_mode and not interrupted:
172172
print(

0 commit comments

Comments
 (0)