Skip to content

Commit 4ff8b07

Browse files
gh-142927: Show self time in flamegraph tooltip (#147706)
We already show self time in differential flamegraphs, but it should be included in regular flamegraphs as well. Display the time spent in the function body excluding callees, not just the total inclusive time.
1 parent c43b490 commit 4ff8b07

File tree

3 files changed

+14
-2
lines changed

3 files changed

+14
-2
lines changed

Lib/profiling/sampling/_flamegraph_assets/flamegraph.js

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -292,6 +292,8 @@ function createPythonTooltip(data) {
292292
}
293293

294294
const timeMs = (d.data.value / 1000).toFixed(2);
295+
const selfSamples = d.data.self || 0;
296+
const selfMs = (selfSamples / 1000).toFixed(2);
295297
const percentage = ((d.data.value / data.value) * 100).toFixed(2);
296298
const calls = d.data.calls || 0;
297299
const childCount = d.children ? d.children.length : 0;
@@ -403,9 +405,14 @@ function createPythonTooltip(data) {
403405
${fileLocationHTML}
404406
</div>
405407
<div class="tooltip-stats">
406-
<span class="tooltip-stat-label">Execution Time:</span>
408+
<span class="tooltip-stat-label">Total Time:</span>
407409
<span class="tooltip-stat-value">${timeMs} ms</span>
408410
411+
${selfSamples > 0 ? `
412+
<span class="tooltip-stat-label">Self Time:</span>
413+
<span class="tooltip-stat-value">${selfMs} ms</span>
414+
` : ''}
415+
409416
<span class="tooltip-stat-label">Percentage:</span>
410417
<span class="tooltip-stat-value accent">${percentage}%</span>
411418
@@ -1271,6 +1278,7 @@ function accumulateInvertedNode(parent, stackFrame, leaf, isDifferential) {
12711278
const newNode = {
12721279
name: stackFrame.name,
12731280
value: 0,
1281+
self: 0,
12741282
children: {},
12751283
filename: stackFrame.filename,
12761284
lineno: stackFrame.lineno,
@@ -1293,6 +1301,7 @@ function accumulateInvertedNode(parent, stackFrame, leaf, isDifferential) {
12931301

12941302
const node = parent.children[key];
12951303
node.value += leaf.value;
1304+
node.self += stackFrame.self || 0;
12961305
if (leaf.threads) {
12971306
leaf.threads.forEach(t => node.threads.add(t));
12981307
}

Lib/profiling/sampling/stack_collector.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -207,6 +207,7 @@ def convert_children(children, min_samples):
207207
child_entry = {
208208
"name": name_idx,
209209
"value": samples,
210+
"self": node.get("self", 0),
210211
"children": [],
211212
"filename": filename_idx,
212213
"lineno": func[1],

Lib/test/test_profiling/test_sampling_profiler/test_collectors.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -435,12 +435,14 @@ def test_flamegraph_collector_basic(self):
435435
strings = data.get("strings", [])
436436
name = resolve_name(data, strings)
437437
self.assertTrue(name.startswith("Program Root: "))
438-
self.assertIn("func2 (file.py:20)", name) # formatted name
438+
self.assertIn("func2 (file.py:20)", name)
439+
self.assertEqual(data["self"], 0) # non-leaf: no self time
439440
children = data.get("children", [])
440441
self.assertEqual(len(children), 1)
441442
child = children[0]
442443
self.assertIn("func1 (file.py:10)", resolve_name(child, strings))
443444
self.assertEqual(child["value"], 1)
445+
self.assertEqual(child["self"], 1) # leaf: all time is self
444446

445447
def test_flamegraph_collector_export(self):
446448
"""Test flamegraph HTML export functionality."""

0 commit comments

Comments
 (0)