Skip to content

Commit 49b0b0b

Browse files
committed
Comma separate thousands, fix plurals
1 parent fba4584 commit 49b0b0b

File tree

3 files changed

+15
-11
lines changed

3 files changed

+15
-11
lines changed

Lib/profiling/sampling/_heatmap_assets/heatmap.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -598,10 +598,12 @@ function populateBytecodePanel(panel, button) {
598598
else if (specPct >= 33) specClass = 'medium';
599599

600600
// Build specialization summary
601+
const instruction_word = instructions.length === 1 ? 'instruction' : 'instructions';
602+
const sample_word = totalSamples === 1 ? 'sample' : 'samples';
601603
let html = `<div class="bytecode-spec-summary ${specClass}">
602604
<span class="spec-pct">${specPct}%</span>
603605
<span class="spec-label">specialized</span>
604-
<span class="spec-detail">(${specializedCount}/${instructions.length} instructions, ${specializedSamples.toLocaleString()}/${totalSamples.toLocaleString()} samples)</span>
606+
<span class="spec-detail">(${specializedCount}/${instructions.length} ${instruction_word}, ${specializedSamples.toLocaleString()}/${totalSamples.toLocaleString()} ${sample_word})</span>
605607
</div>`;
606608

607609
html += '<div class="bytecode-header">' +

Lib/profiling/sampling/heatmap_collector.py

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -431,10 +431,11 @@ def _render_file_item(self, stat: FileStats, indent: str = '') -> str:
431431
bar_width = min(stat.percentage, 100)
432432

433433
html_file = self.file_index[stat.filename]
434+
s = "" if stat.total_samples == 1 else "s"
434435

435436
return (f'{indent}<div class="file-item">\n'
436437
f'{indent} <a href="{html_file}" class="file-link" title="{full_path}">📄 {module_name}</a>\n'
437-
f'{indent} <span class="file-samples">{stat.total_samples:,} samples</span>\n'
438+
f'{indent} <span class="file-samples">{stat.total_samples:,} sample{s}</span>\n'
438439
f'{indent} <div class="heatmap-bar-container"><div class="heatmap-bar" style="width: {bar_width}px; height: {self.heatmap_bar_height}px;" data-intensity="{intensity:.3f}"></div></div>\n'
439440
f'{indent}</div>\n')
440441

@@ -761,7 +762,8 @@ def _print_export_summary(self, output_dir, file_stats: List[FileStats]):
761762
"""Print summary of exported heatmap."""
762763
print(f"Heatmap output written to {output_dir}/")
763764
print(f" - Index: {output_dir / 'index.html'}")
764-
print(f" - {len(file_stats)} source file(s) analyzed")
765+
s = "" if len(file_stats) == 1 else "s"
766+
print(f" - {len(file_stats)} source file{s} analyzed")
765767

766768
def _calculate_file_stats(self) -> List[FileStats]:
767769
"""Calculate statistics for each file.
@@ -859,10 +861,10 @@ def _generate_index_html(self, index_path: Path, file_stats: List[FileStats]):
859861
"<!-- INLINE_JS -->": f"<script>\n{self._template_loader.index_js}\n</script>",
860862
"<!-- PYTHON_LOGO -->": self._template_loader.logo_html,
861863
"<!-- PYTHON_VERSION -->": f"{sys.version_info.major}.{sys.version_info.minor}",
862-
"<!-- NUM_FILES -->": str(len(file_stats)),
864+
"<!-- NUM_FILES -->": f"{len(file_stats):,}",
863865
"<!-- TOTAL_SAMPLES -->": f"{self._total_samples:,}",
864-
"<!-- DURATION -->": f"{self.stats.get('duration_sec', 0):.1f}s",
865-
"<!-- SAMPLE_RATE -->": f"{self.stats.get('sample_rate', 0):.1f}",
866+
"<!-- DURATION -->": f"{self.stats.get('duration_sec', 0):,.1f}s",
867+
"<!-- SAMPLE_RATE -->": f"{self.stats.get('sample_rate', 0):,.1f}",
866868
"<!-- ERROR_RATE -->": error_rate_str,
867869
"<!-- ERROR_RATE_WIDTH -->": str(error_rate_width),
868870
"<!-- ERROR_RATE_CLASS -->": error_rate_class,
@@ -908,10 +910,10 @@ def _generate_file_html(self, output_path: Path, filename: str,
908910
"<!-- FILENAME -->": html.escape(filename),
909911
"<!-- TOTAL_SAMPLES -->": f"{file_stat.total_samples:,}",
910912
"<!-- TOTAL_SELF_SAMPLES -->": f"{file_stat.total_self_samples:,}",
911-
"<!-- NUM_LINES -->": str(file_stat.num_lines),
913+
"<!-- NUM_LINES -->": f"{file_stat.num_lines:,}",
912914
"<!-- PERCENTAGE -->": f"{file_stat.percentage:.2f}",
913-
"<!-- MAX_SAMPLES -->": str(file_stat.max_samples),
914-
"<!-- MAX_SELF_SAMPLES -->": str(file_stat.max_self_samples),
915+
"<!-- MAX_SAMPLES -->": f"{file_stat.max_samples:,}",
916+
"<!-- MAX_SELF_SAMPLES -->": f"{file_stat.max_self_samples:,}",
915917
"<!-- CODE_LINES -->": ''.join(code_lines_html),
916918
"<!-- INLINE_CSS -->": f"<style>\n{self._template_loader.file_css}\n</style>",
917919
"<!-- INLINE_JS -->": f"<script>\n{self._template_loader.file_js}\n</script>",

Lib/profiling/sampling/sample.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -135,8 +135,8 @@ def sample(self, collector, duration_sec=10, *, async_aware=False):
135135
# Don't print stats for live mode (curses is handling display)
136136
is_live_mode = LiveStatsCollector is not None and isinstance(collector, LiveStatsCollector)
137137
if not is_live_mode:
138-
print(f"Captured {num_samples} samples in {running_time:.2f} seconds")
139-
print(f"Sample rate: {sample_rate:.2f} samples/sec")
138+
print(f"Captured {num_samples:,} samples in {running_time:.2f} seconds")
139+
print(f"Sample rate: {sample_rate:,.2f} samples/sec")
140140
print(f"Error rate: {error_rate:.2f}%")
141141

142142
# Print unwinder stats if stats collection is enabled

0 commit comments

Comments
 (0)