}
const timeMs = (d.data.value / 1000).toFixed(2);
+ const selfSamples = d.data.self || 0;
+ const selfMs = (selfSamples / 1000).toFixed(2);
const percentage = ((d.data.value / data.value) * 100).toFixed(2);
const calls = d.data.calls || 0;
const childCount = d.children ? d.children.length : 0;
${fileLocationHTML}
</div>
<div class="tooltip-stats">
- <span class="tooltip-stat-label">Execution Time:</span>
+ <span class="tooltip-stat-label">Total Time:</span>
<span class="tooltip-stat-value">${timeMs} ms</span>
+ ${selfSamples > 0 ? `
+ <span class="tooltip-stat-label">Self Time:</span>
+ <span class="tooltip-stat-value">${selfMs} ms</span>
+ ` : ''}
+
<span class="tooltip-stat-label">Percentage:</span>
<span class="tooltip-stat-value accent">${percentage}%</span>
const newNode = {
name: stackFrame.name,
value: 0,
+ self: 0,
children: {},
filename: stackFrame.filename,
lineno: stackFrame.lineno,
const node = parent.children[key];
node.value += leaf.value;
+ node.self += stackFrame.self || 0;
if (leaf.threads) {
leaf.threads.forEach(t => node.threads.add(t));
}
strings = data.get("strings", [])
name = resolve_name(data, strings)
self.assertTrue(name.startswith("Program Root: "))
- self.assertIn("func2 (file.py:20)", name) # formatted name
+ self.assertIn("func2 (file.py:20)", name)
+ self.assertEqual(data["self"], 0) # non-leaf: no self time
children = data.get("children", [])
self.assertEqual(len(children), 1)
child = children[0]
self.assertIn("func1 (file.py:10)", resolve_name(child, strings))
self.assertEqual(child["value"], 1)
+ self.assertEqual(child["self"], 1) # leaf: all time is self
def test_flamegraph_collector_export(self):
"""Test flamegraph HTML export functionality."""